aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile7
-rw-r--r--tools/arch/alpha/include/uapi/asm/bitsperlong.h8
-rw-r--r--tools/arch/arm/include/uapi/asm/kvm.h224
-rw-r--r--tools/arch/arm/include/uapi/asm/perf_regs.h23
-rw-r--r--tools/arch/arm64/include/uapi/asm/bitsperlong.h23
-rw-r--r--tools/arch/arm64/include/uapi/asm/kvm.h258
-rw-r--r--tools/arch/arm64/include/uapi/asm/perf_regs.h40
-rw-r--r--tools/arch/frv/include/uapi/asm/bitsperlong.h1
-rw-r--r--tools/arch/h8300/include/asm/bitsperlong.h14
-rw-r--r--tools/arch/hexagon/include/uapi/asm/bitsperlong.h26
-rw-r--r--tools/arch/ia64/include/uapi/asm/bitsperlong.h8
-rw-r--r--tools/arch/m32r/include/uapi/asm/bitsperlong.h1
-rw-r--r--tools/arch/microblaze/include/uapi/asm/bitsperlong.h1
-rw-r--r--tools/arch/mips/include/uapi/asm/bitsperlong.h8
-rw-r--r--tools/arch/mips/include/uapi/asm/kvm.h208
-rw-r--r--tools/arch/mn10300/include/uapi/asm/bitsperlong.h1
-rw-r--r--tools/arch/parisc/include/uapi/asm/bitsperlong.h14
-rw-r--r--tools/arch/powerpc/include/uapi/asm/bitsperlong.h12
-rw-r--r--tools/arch/powerpc/include/uapi/asm/kvm.h612
-rw-r--r--tools/arch/powerpc/include/uapi/asm/perf_regs.h50
-rw-r--r--tools/arch/s390/include/uapi/asm/bitsperlong.h12
-rw-r--r--tools/arch/s390/include/uapi/asm/kvm.h192
-rw-r--r--tools/arch/s390/include/uapi/asm/kvm_perf.h25
-rw-r--r--tools/arch/s390/include/uapi/asm/sie.h250
-rw-r--r--tools/arch/score/include/uapi/asm/bitsperlong.h6
-rw-r--r--tools/arch/sparc/include/uapi/asm/bitsperlong.h12
-rw-r--r--tools/arch/tile/include/uapi/asm/bitsperlong.h26
-rw-r--r--tools/arch/x86/include/asm/cpufeatures.h316
-rw-r--r--tools/arch/x86/include/asm/disabled-features.h60
-rw-r--r--tools/arch/x86/include/asm/required-features.h103
-rw-r--r--tools/arch/x86/include/asm/unistd_32.h12
-rw-r--r--tools/arch/x86/include/asm/unistd_64.h12
-rw-r--r--tools/arch/x86/include/uapi/asm/bitsperlong.h12
-rw-r--r--tools/arch/x86/include/uapi/asm/kvm.h360
-rw-r--r--tools/arch/x86/include/uapi/asm/kvm_perf.h16
-rw-r--r--tools/arch/x86/include/uapi/asm/perf_regs.h33
-rw-r--r--tools/arch/x86/include/uapi/asm/svm.h178
-rw-r--r--tools/arch/x86/include/uapi/asm/vmx.h136
-rw-r--r--tools/arch/x86/lib/memcpy_64.S297
-rw-r--r--tools/arch/x86/lib/memset_64.S138
-rw-r--r--tools/build/Makefile.feature5
-rw-r--r--tools/build/feature/Makefile14
-rw-r--r--tools/build/feature/test-all.c15
-rw-r--r--tools/build/feature/test-libelf-gelf_getnote.c7
-rw-r--r--tools/build/feature/test-libelf-getshdrstrndx.c8
-rw-r--r--tools/build/feature/test-sdt.c7
-rw-r--r--tools/gpio/Build3
-rw-r--r--tools/gpio/Makefile75
-rw-r--r--tools/gpio/gpio-event-mon.c192
-rw-r--r--tools/gpio/gpio-hammer.c189
-rwxr-xr-xtools/hv/bondvf.sh193
-rw-r--r--tools/iio/Makefile21
-rw-r--r--tools/iio/iio_generic_buffer.c (renamed from tools/iio/generic_buffer.c)261
-rw-r--r--tools/include/asm-generic/bitops/__ffs.h1
-rw-r--r--tools/include/asm-generic/bitops/__fls.h44
-rw-r--r--tools/include/asm-generic/bitops/arch_hweight.h26
-rw-r--r--tools/include/asm-generic/bitops/atomic.h1
-rw-r--r--tools/include/asm-generic/bitops/const_hweight.h44
-rw-r--r--tools/include/asm-generic/bitops/fls.h42
-rw-r--r--tools/include/asm-generic/bitops/fls64.h37
-rw-r--r--tools/include/asm-generic/bitsperlong.h20
-rw-r--r--tools/include/asm/alternative-asm.h (renamed from tools/perf/util/include/asm/alternative-asm.h)4
-rw-r--r--tools/include/linux/bitops.h4
-rw-r--r--tools/include/linux/compiler.h11
-rw-r--r--tools/include/linux/hash.h105
-rw-r--r--tools/include/linux/kernel.h28
-rw-r--r--tools/include/linux/poison.h91
-rw-r--r--tools/include/linux/string.h4
-rw-r--r--tools/include/uapi/asm-generic/bitsperlong.h15
-rw-r--r--tools/include/uapi/linux/bpf.h389
-rw-r--r--tools/include/uapi/linux/bpf_common.h55
-rw-r--r--tools/include/uapi/linux/hw_breakpoint.h30
-rw-r--r--tools/include/uapi/linux/perf_event.h983
-rw-r--r--tools/lib/api/Build5
-rw-r--r--tools/lib/api/Makefile10
-rw-r--r--tools/lib/api/fd/array.c5
-rw-r--r--tools/lib/api/fd/array.h4
-rw-r--r--tools/lib/api/fs/fs.c7
-rw-r--r--tools/lib/api/fs/tracing_path.c3
-rw-r--r--tools/lib/bpf/Makefile8
-rw-r--r--tools/lib/bpf/bpf.c13
-rw-r--r--tools/lib/bpf/bpf.h13
-rw-r--r--tools/lib/bpf/libbpf.c156
-rw-r--r--tools/lib/bpf/libbpf.h50
-rw-r--r--tools/lib/str_error_r.c26
-rw-r--r--tools/lib/subcmd/Makefile8
-rw-r--r--tools/lib/subcmd/run-command.c5
-rw-r--r--tools/lib/traceevent/event-parse.c11
-rw-r--r--tools/lib/traceevent/parse-filter.c18
-rw-r--r--tools/lib/vsprintf.c24
-rw-r--r--tools/objtool/.gitignore1
-rw-r--r--tools/objtool/Build7
-rw-r--r--tools/objtool/Makefile15
-rw-r--r--tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk11
-rw-r--r--tools/objtool/arch/x86/insn/inat.h17
-rw-r--r--tools/objtool/arch/x86/insn/insn.c18
-rw-r--r--tools/objtool/arch/x86/insn/insn.h12
-rw-r--r--tools/objtool/arch/x86/insn/x86-opcode-map.txt265
-rw-r--r--tools/objtool/builtin-check.c141
-rw-r--r--tools/objtool/elf.c7
-rw-r--r--tools/perf/.gitignore1
-rw-r--r--tools/perf/Documentation/android.txt16
-rw-r--r--tools/perf/Documentation/perf-annotate.txt7
-rw-r--r--tools/perf/Documentation/perf-buildid-cache.txt3
-rw-r--r--tools/perf/Documentation/perf-data.txt4
-rw-r--r--tools/perf/Documentation/perf-mem.txt3
-rw-r--r--tools/perf/Documentation/perf-probe.txt32
-rw-r--r--tools/perf/Documentation/perf-record.txt29
-rw-r--r--tools/perf/Documentation/perf-report.txt7
-rw-r--r--tools/perf/Documentation/perf-script.txt31
-rw-r--r--tools/perf/Documentation/perf-stat.txt32
-rw-r--r--tools/perf/Documentation/perf-test.txt4
-rw-r--r--tools/perf/Documentation/perf.data-file-format.txt442
-rw-r--r--tools/perf/MANIFEST54
-rw-r--r--tools/perf/Makefile.perf87
-rw-r--r--tools/perf/arch/arm/util/Build2
-rw-r--r--tools/perf/arch/arm64/util/Build2
-rw-r--r--tools/perf/arch/arm64/util/unwind-libunwind.c4
-rw-r--r--tools/perf/arch/common.c20
-rw-r--r--tools/perf/arch/common.h1
-rw-r--r--tools/perf/arch/s390/util/Build2
-rw-r--r--tools/perf/arch/s390/util/machine.c19
-rw-r--r--tools/perf/arch/x86/entry/syscalls/syscall_64.tbl2
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-32.c1020
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-64.c942
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-src.c1793
-rw-r--r--tools/perf/arch/x86/tests/perf-time-to-tsc.c6
-rw-r--r--tools/perf/arch/x86/tests/rdpmc.c8
-rw-r--r--tools/perf/arch/x86/util/Build3
-rw-r--r--tools/perf/arch/x86/util/auxtrace.c2
-rw-r--r--tools/perf/arch/x86/util/group.c27
-rw-r--r--tools/perf/arch/x86/util/intel-bts.c8
-rw-r--r--tools/perf/arch/x86/util/intel-pt.c10
-rw-r--r--tools/perf/arch/x86/util/tsc.c2
-rw-r--r--tools/perf/arch/x86/util/unwind-libunwind.c6
-rw-r--r--tools/perf/bench/futex-hash.c15
-rw-r--r--tools/perf/bench/futex-lock-pi.c11
-rw-r--r--tools/perf/bench/futex-requeue.c11
-rw-r--r--tools/perf/bench/futex-wake-parallel.c11
-rw-r--r--tools/perf/bench/futex-wake.c11
-rw-r--r--tools/perf/bench/mem-memcpy-x86-64-asm.S2
-rw-r--r--tools/perf/bench/mem-memset-x86-64-asm.S2
-rw-r--r--tools/perf/bench/numa.c4
-rw-r--r--tools/perf/builtin-annotate.c7
-rw-r--r--tools/perf/builtin-buildid-cache.c21
-rw-r--r--tools/perf/builtin-config.c21
-rw-r--r--tools/perf/builtin-data.c11
-rw-r--r--tools/perf/builtin-diff.c29
-rw-r--r--tools/perf/builtin-evlist.c2
-rw-r--r--tools/perf/builtin-help.c10
-rw-r--r--tools/perf/builtin-inject.c8
-rw-r--r--tools/perf/builtin-kmem.c5
-rw-r--r--tools/perf/builtin-kvm.c12
-rw-r--r--tools/perf/builtin-list.c6
-rw-r--r--tools/perf/builtin-mem.c1
-rw-r--r--tools/perf/builtin-probe.c38
-rw-r--r--tools/perf/builtin-record.c211
-rw-r--r--tools/perf/builtin-report.c18
-rw-r--r--tools/perf/builtin-sched.c2
-rw-r--r--tools/perf/builtin-script.c136
-rw-r--r--tools/perf/builtin-stat.c199
-rw-r--r--tools/perf/builtin-top.c18
-rw-r--r--tools/perf/builtin-trace.c19
-rw-r--r--tools/perf/config/Makefile89
-rw-r--r--tools/perf/jvmti/jvmti_agent.c10
-rw-r--r--tools/perf/perf-sys.h19
-rw-r--r--tools/perf/perf.c58
-rw-r--r--tools/perf/perf.h2
-rwxr-xr-xtools/perf/python/tracepoint.py47
-rwxr-xr-xtools/perf/scripts/python/bin/stackcollapse-record8
-rwxr-xr-xtools/perf/scripts/python/bin/stackcollapse-report3
-rw-r--r--tools/perf/scripts/python/netdev-times.py11
-rwxr-xr-xtools/perf/scripts/python/stackcollapse.py125
-rw-r--r--tools/perf/tests/Build2
-rw-r--r--tools/perf/tests/backward-ring-buffer.c18
-rw-r--r--tools/perf/tests/bpf-script-example.c4
-rw-r--r--tools/perf/tests/bpf.c10
-rw-r--r--tools/perf/tests/builtin-test.c69
-rw-r--r--tools/perf/tests/cpumap.c31
-rw-r--r--tools/perf/tests/dso-data.c6
-rw-r--r--tools/perf/tests/event-times.c5
-rw-r--r--tools/perf/tests/evsel-roundtrip-name.c2
-rw-r--r--tools/perf/tests/fdarray.c9
-rw-r--r--tools/perf/tests/hists_cumulate.c4
-rw-r--r--tools/perf/tests/hists_filter.c4
-rw-r--r--tools/perf/tests/hists_link.c8
-rw-r--r--tools/perf/tests/is_printable_array.c36
-rw-r--r--tools/perf/tests/kmod-path.c1
-rw-r--r--tools/perf/tests/llvm.c1
-rw-r--r--tools/perf/tests/make5
-rw-r--r--tools/perf/tests/mmap-basic.c11
-rw-r--r--tools/perf/tests/openat-syscall-all-cpus.c7
-rw-r--r--tools/perf/tests/openat-syscall-tp-fields.c11
-rw-r--r--tools/perf/tests/openat-syscall.c2
-rw-r--r--tools/perf/tests/parse-events.c8
-rw-r--r--tools/perf/tests/parse-no-sample-id-all.c3
-rw-r--r--tools/perf/tests/perf-record.c11
-rw-r--r--tools/perf/tests/sdt.c115
-rw-r--r--tools/perf/tests/sw-clock.c4
-rw-r--r--tools/perf/tests/switch-tracking.c2
-rw-r--r--tools/perf/tests/task-exit.c4
-rw-r--r--tools/perf/tests/tests.h3
-rw-r--r--tools/perf/tests/thread-map.c16
-rw-r--r--tools/perf/trace/beauty/eventfd.c2
-rw-r--r--tools/perf/trace/beauty/flock.c17
-rw-r--r--tools/perf/trace/beauty/futex_op.c16
-rw-r--r--tools/perf/trace/beauty/mmap.c77
-rw-r--r--tools/perf/trace/beauty/msg_flags.c1
-rw-r--r--tools/perf/trace/beauty/open_flags.c15
-rw-r--r--tools/perf/trace/beauty/sched_policy.c3
-rw-r--r--tools/perf/trace/beauty/seccomp.c2
-rw-r--r--tools/perf/ui/browser.c2
-rw-r--r--tools/perf/ui/browsers/annotate.c21
-rw-r--r--tools/perf/ui/browsers/hists.c150
-rw-r--r--tools/perf/ui/browsers/hists.h32
-rw-r--r--tools/perf/ui/gtk/hists.c4
-rw-r--r--tools/perf/ui/gtk/util.c1
-rw-r--r--tools/perf/ui/helpline.c1
-rw-r--r--tools/perf/ui/hist.c13
-rw-r--r--tools/perf/ui/setup.c7
-rw-r--r--tools/perf/ui/stdio/hist.c133
-rw-r--r--tools/perf/ui/tui/setup.c2
-rw-r--r--tools/perf/ui/ui.h4
-rw-r--r--tools/perf/util/Build9
-rw-r--r--tools/perf/util/alias.c2
-rw-r--r--tools/perf/util/annotate.c27
-rw-r--r--tools/perf/util/annotate.h3
-rw-r--r--tools/perf/util/auxtrace.h2
-rw-r--r--tools/perf/util/bpf-loader.c203
-rw-r--r--tools/perf/util/bpf-loader.h12
-rw-r--r--tools/perf/util/build-id.c320
-rw-r--r--tools/perf/util/build-id.h8
-rw-r--r--tools/perf/util/cache.h23
-rw-r--r--tools/perf/util/callchain.h2
-rw-r--r--tools/perf/util/cgroup.c4
-rw-r--r--tools/perf/util/cloexec.c18
-rw-r--r--tools/perf/util/color.c4
-rw-r--r--tools/perf/util/config.c160
-rw-r--r--tools/perf/util/config.h40
-rw-r--r--tools/perf/util/cpumap.c68
-rw-r--r--tools/perf/util/cpumap.h3
-rw-r--r--tools/perf/util/data-convert-bt.c200
-rw-r--r--tools/perf/util/data-convert-bt.h4
-rw-r--r--tools/perf/util/data-convert.h9
-rw-r--r--tools/perf/util/data.c4
-rw-r--r--tools/perf/util/db-export.c13
-rw-r--r--tools/perf/util/debug.h2
-rw-r--r--tools/perf/util/demangle-rust.c269
-rw-r--r--tools/perf/util/demangle-rust.h7
-rw-r--r--tools/perf/util/dso.c28
-rw-r--r--tools/perf/util/dso.h8
-rw-r--r--tools/perf/util/env.c5
-rw-r--r--tools/perf/util/env.h10
-rw-r--r--tools/perf/util/event.c2
-rw-r--r--tools/perf/util/evlist.c352
-rw-r--r--tools/perf/util/evlist.h92
-rw-r--r--tools/perf/util/evsel.c98
-rw-r--r--tools/perf/util/evsel.h27
-rw-r--r--tools/perf/util/group.h7
-rw-r--r--tools/perf/util/header.c94
-rw-r--r--tools/perf/util/help-unknown-cmd.c2
-rw-r--r--tools/perf/util/hist.c228
-rw-r--r--tools/perf/util/hist.h32
-rw-r--r--tools/perf/util/include/asm/byteorder.h2
-rw-r--r--tools/perf/util/include/asm/unistd_32.h1
-rw-r--r--tools/perf/util/include/asm/unistd_64.h1
-rw-r--r--tools/perf/util/include/linux/const.h1
-rw-r--r--tools/perf/util/intel-bts.c24
-rw-r--r--tools/perf/util/intel-pt-decoder/Build5
-rw-r--r--tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk11
-rw-r--r--tools/perf/util/intel-pt-decoder/inat.h17
-rw-r--r--tools/perf/util/intel-pt-decoder/insn.c18
-rw-r--r--tools/perf/util/intel-pt-decoder/insn.h12
-rw-r--r--tools/perf/util/intel-pt-decoder/x86-opcode-map.txt265
-rw-r--r--tools/perf/util/intel-pt.c26
-rw-r--r--tools/perf/util/intlist.h8
-rw-r--r--tools/perf/util/jitdump.c2
-rw-r--r--tools/perf/util/levenshtein.c4
-rw-r--r--tools/perf/util/libunwind/arm64.c40
-rw-r--r--tools/perf/util/libunwind/x86_32.c43
-rw-r--r--tools/perf/util/llvm-utils.c53
-rw-r--r--tools/perf/util/llvm-utils.h5
-rw-r--r--tools/perf/util/machine.c28
-rw-r--r--tools/perf/util/machine.h1
-rw-r--r--tools/perf/util/map.c12
-rw-r--r--tools/perf/util/map.h2
-rw-r--r--tools/perf/util/mem-events.c17
-rw-r--r--tools/perf/util/mem-events.h1
-rw-r--r--tools/perf/util/parse-events.c142
-rw-r--r--tools/perf/util/parse-events.h7
-rw-r--r--tools/perf/util/parse-events.l4
-rw-r--r--tools/perf/util/path.c67
-rw-r--r--tools/perf/util/probe-event.c526
-rw-r--r--tools/perf/util/probe-event.h6
-rw-r--r--tools/perf/util/probe-file.c547
-rw-r--r--tools/perf/util/probe-file.h42
-rw-r--r--tools/perf/util/probe-finder.c4
-rw-r--r--tools/perf/util/python-ext-sources1
-rw-r--r--tools/perf/util/python.c152
-rw-r--r--tools/perf/util/quote.c4
-rw-r--r--tools/perf/util/quote.h3
-rw-r--r--tools/perf/util/rb_resort.h4
-rw-r--r--tools/perf/util/record.c8
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c29
-rw-r--r--tools/perf/util/session.c36
-rw-r--r--tools/perf/util/sort.c36
-rw-r--r--tools/perf/util/sort.h6
-rw-r--r--tools/perf/util/stat-shadow.c162
-rw-r--r--tools/perf/util/stat.c11
-rw-r--r--tools/perf/util/stat.h5
-rw-r--r--tools/perf/util/strbuf.c2
-rw-r--r--tools/perf/util/strbuf.h3
-rw-r--r--tools/perf/util/strlist.h4
-rw-r--r--tools/perf/util/symbol-elf.c271
-rw-r--r--tools/perf/util/symbol.c75
-rw-r--r--tools/perf/util/symbol.h22
-rw-r--r--tools/perf/util/target.c3
-rw-r--r--tools/perf/util/thread-stack.c7
-rw-r--r--tools/perf/util/thread-stack.h1
-rw-r--r--tools/perf/util/thread.c61
-rw-r--r--tools/perf/util/thread.h11
-rw-r--r--tools/perf/util/thread_map.c4
-rw-r--r--tools/perf/util/trace-event.c8
-rw-r--r--tools/perf/util/trace-event.h2
-rw-r--r--tools/perf/util/unwind-libunwind-local.c699
-rw-r--r--tools/perf/util/unwind-libunwind.c695
-rw-r--r--tools/perf/util/unwind.h34
-rw-r--r--tools/perf/util/util.c48
-rw-r--r--tools/perf/util/util.h7
-rw-r--r--tools/perf/util/vdso.c40
-rw-r--r--tools/power/acpi/Makefile.config7
-rw-r--r--tools/power/x86/turbostat/Makefile4
-rw-r--r--tools/power/x86/turbostat/turbostat.82
-rw-r--r--tools/power/x86/turbostat/turbostat.c2
-rw-r--r--tools/scripts/Makefile.arch41
-rw-r--r--tools/testing/nvdimm/Kbuild10
-rw-r--r--tools/testing/nvdimm/config_check.c1
-rw-r--r--tools/testing/nvdimm/pmem-dax.c54
-rw-r--r--tools/testing/nvdimm/test/Kbuild2
-rw-r--r--tools/testing/nvdimm/test/iomap.c38
-rw-r--r--tools/testing/nvdimm/test/nfit.c199
-rw-r--r--tools/testing/nvdimm/test/nfit_test.h2
-rw-r--r--tools/testing/selftests/powerpc/Makefile3
-rw-r--r--tools/testing/selftests/powerpc/alignment/.gitignore5
-rw-r--r--tools/testing/selftests/powerpc/alignment/Makefile10
-rw-r--r--tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c41
-rw-r--r--tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c53
-rw-r--r--tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h26
-rw-r--r--tools/testing/selftests/powerpc/alignment/copy_unaligned.c41
-rw-r--r--tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c43
-rw-r--r--tools/testing/selftests/powerpc/alignment/paste_unaligned.c43
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/.gitignore2
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/Makefile3
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/context_switch.c17
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/futex_bench.c42
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/mmap_bench.c41
-rw-r--r--tools/testing/selftests/powerpc/instructions.h68
-rw-r--r--tools/testing/selftests/powerpc/mm/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/mm/Makefile4
-rw-r--r--tools/testing/selftests/powerpc/mm/prot_sao.c42
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/.gitignore2
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c143
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h39
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c37
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c2
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.c6
-rw-r--r--tools/testing/selftests/powerpc/reg.h5
-rw-r--r--tools/testing/selftests/powerpc/tm/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/tm/Makefile7
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-exec.c70
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-syscall.c15
-rw-r--r--tools/testing/selftests/powerpc/tm/tm.h23
-rw-r--r--tools/testing/selftests/powerpc/utils.h5
-rw-r--r--tools/testing/selftests/rcutorture/bin/functions.sh12
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh34
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm.sh2
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/parse-console.sh7
-rw-r--r--tools/testing/selftests/rcutorture/doc/initrd.txt22
-rw-r--r--tools/testing/selftests/seccomp/seccomp_bpf.c176
-rw-r--r--tools/testing/selftests/x86/Makefile4
-rw-r--r--tools/testing/selftests/x86/mpx-debug.h14
-rw-r--r--tools/testing/selftests/x86/mpx-dig.c498
-rw-r--r--tools/testing/selftests/x86/mpx-hw.h123
-rw-r--r--tools/testing/selftests/x86/mpx-mini-test.c1585
-rw-r--r--tools/testing/selftests/x86/mpx-mm.h9
-rw-r--r--tools/testing/selftests/x86/test_mremap_vdso.c111
-rw-r--r--tools/virtio/ringtest/Makefile5
-rw-r--r--tools/virtio/ringtest/ptr_ring.c197
-rw-r--r--tools/vm/page_owner_sort.c9
390 files changed, 22191 insertions, 2898 deletions
diff --git a/tools/Makefile b/tools/Makefile
index f10b64d8c674..daa8fb3e4363 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -85,7 +85,7 @@ tmon: FORCE
85freefall: FORCE 85freefall: FORCE
86 $(call descend,laptop/$@) 86 $(call descend,laptop/$@)
87 87
88all: acpi cgroup cpupower hv firewire lguest \ 88all: acpi cgroup cpupower gpio hv firewire lguest \
89 perf selftests turbostat usb \ 89 perf selftests turbostat usb \
90 virtio vm net x86_energy_perf_policy \ 90 virtio vm net x86_energy_perf_policy \
91 tmon freefall objtool 91 tmon freefall objtool
@@ -96,7 +96,7 @@ acpi_install:
96cpupower_install: 96cpupower_install:
97 $(call descend,power/$(@:_install=),install) 97 $(call descend,power/$(@:_install=),install)
98 98
99cgroup_install firewire_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install objtool_install: 99cgroup_install firewire_install gpio_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install objtool_install:
100 $(call descend,$(@:_install=),install) 100 $(call descend,$(@:_install=),install)
101 101
102selftests_install: 102selftests_install:
@@ -114,7 +114,8 @@ freefall_install:
114kvm_stat_install: 114kvm_stat_install:
115 $(call descend,kvm/$(@:_install=),install) 115 $(call descend,kvm/$(@:_install=),install)
116 116
117install: acpi_install cgroup_install cpupower_install hv_install firewire_install lguest_install \ 117install: acpi_install cgroup_install cpupower_install gpio_install \
118 hv_install firewire_install lguest_install \
118 perf_install selftests_install turbostat_install usb_install \ 119 perf_install selftests_install turbostat_install usb_install \
119 virtio_install vm_install net_install x86_energy_perf_policy_install \ 120 virtio_install vm_install net_install x86_energy_perf_policy_install \
120 tmon_install freefall_install objtool_install kvm_stat_install 121 tmon_install freefall_install objtool_install kvm_stat_install
diff --git a/tools/arch/alpha/include/uapi/asm/bitsperlong.h b/tools/arch/alpha/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..ad57f7868203
--- /dev/null
+++ b/tools/arch/alpha/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,8 @@
1#ifndef __ASM_ALPHA_BITSPERLONG_H
2#define __ASM_ALPHA_BITSPERLONG_H
3
4#define __BITS_PER_LONG 64
5
6#include <asm-generic/bitsperlong.h>
7
8#endif /* __ASM_ALPHA_BITSPERLONG_H */
diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h
new file mode 100644
index 000000000000..a2b3eb313a25
--- /dev/null
+++ b/tools/arch/arm/include/uapi/asm/kvm.h
@@ -0,0 +1,224 @@
1/*
2 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
3 * Author: Christoffer Dall <c.dall@virtualopensystems.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2, as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#ifndef __ARM_KVM_H__
20#define __ARM_KVM_H__
21
22#include <linux/types.h>
23#include <linux/psci.h>
24#include <asm/ptrace.h>
25
26#define __KVM_HAVE_GUEST_DEBUG
27#define __KVM_HAVE_IRQ_LINE
28#define __KVM_HAVE_READONLY_MEM
29
30#define KVM_REG_SIZE(id) \
31 (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
32
33/* Valid for svc_regs, abt_regs, und_regs, irq_regs in struct kvm_regs */
34#define KVM_ARM_SVC_sp svc_regs[0]
35#define KVM_ARM_SVC_lr svc_regs[1]
36#define KVM_ARM_SVC_spsr svc_regs[2]
37#define KVM_ARM_ABT_sp abt_regs[0]
38#define KVM_ARM_ABT_lr abt_regs[1]
39#define KVM_ARM_ABT_spsr abt_regs[2]
40#define KVM_ARM_UND_sp und_regs[0]
41#define KVM_ARM_UND_lr und_regs[1]
42#define KVM_ARM_UND_spsr und_regs[2]
43#define KVM_ARM_IRQ_sp irq_regs[0]
44#define KVM_ARM_IRQ_lr irq_regs[1]
45#define KVM_ARM_IRQ_spsr irq_regs[2]
46
47/* Valid only for fiq_regs in struct kvm_regs */
48#define KVM_ARM_FIQ_r8 fiq_regs[0]
49#define KVM_ARM_FIQ_r9 fiq_regs[1]
50#define KVM_ARM_FIQ_r10 fiq_regs[2]
51#define KVM_ARM_FIQ_fp fiq_regs[3]
52#define KVM_ARM_FIQ_ip fiq_regs[4]
53#define KVM_ARM_FIQ_sp fiq_regs[5]
54#define KVM_ARM_FIQ_lr fiq_regs[6]
55#define KVM_ARM_FIQ_spsr fiq_regs[7]
56
57struct kvm_regs {
58 struct pt_regs usr_regs; /* R0_usr - R14_usr, PC, CPSR */
59 unsigned long svc_regs[3]; /* SP_svc, LR_svc, SPSR_svc */
60 unsigned long abt_regs[3]; /* SP_abt, LR_abt, SPSR_abt */
61 unsigned long und_regs[3]; /* SP_und, LR_und, SPSR_und */
62 unsigned long irq_regs[3]; /* SP_irq, LR_irq, SPSR_irq */
63 unsigned long fiq_regs[8]; /* R8_fiq - R14_fiq, SPSR_fiq */
64};
65
66/* Supported Processor Types */
67#define KVM_ARM_TARGET_CORTEX_A15 0
68#define KVM_ARM_TARGET_CORTEX_A7 1
69#define KVM_ARM_NUM_TARGETS 2
70
71/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
72#define KVM_ARM_DEVICE_TYPE_SHIFT 0
73#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
74#define KVM_ARM_DEVICE_ID_SHIFT 16
75#define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT)
76
77/* Supported device IDs */
78#define KVM_ARM_DEVICE_VGIC_V2 0
79
80/* Supported VGIC address types */
81#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
82#define KVM_VGIC_V2_ADDR_TYPE_CPU 1
83
84#define KVM_VGIC_V2_DIST_SIZE 0x1000
85#define KVM_VGIC_V2_CPU_SIZE 0x2000
86
87#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
88#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
89
90struct kvm_vcpu_init {
91 __u32 target;
92 __u32 features[7];
93};
94
95struct kvm_sregs {
96};
97
98struct kvm_fpu {
99};
100
101struct kvm_guest_debug_arch {
102};
103
104struct kvm_debug_exit_arch {
105};
106
107struct kvm_sync_regs {
108};
109
110struct kvm_arch_memory_slot {
111};
112
113/* If you need to interpret the index values, here is the key: */
114#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
115#define KVM_REG_ARM_COPROC_SHIFT 16
116#define KVM_REG_ARM_32_OPC2_MASK 0x0000000000000007
117#define KVM_REG_ARM_32_OPC2_SHIFT 0
118#define KVM_REG_ARM_OPC1_MASK 0x0000000000000078
119#define KVM_REG_ARM_OPC1_SHIFT 3
120#define KVM_REG_ARM_CRM_MASK 0x0000000000000780
121#define KVM_REG_ARM_CRM_SHIFT 7
122#define KVM_REG_ARM_32_CRN_MASK 0x0000000000007800
123#define KVM_REG_ARM_32_CRN_SHIFT 11
124
125#define ARM_CP15_REG_SHIFT_MASK(x,n) \
126 (((x) << KVM_REG_ARM_ ## n ## _SHIFT) & KVM_REG_ARM_ ## n ## _MASK)
127
128#define __ARM_CP15_REG(op1,crn,crm,op2) \
129 (KVM_REG_ARM | (15 << KVM_REG_ARM_COPROC_SHIFT) | \
130 ARM_CP15_REG_SHIFT_MASK(op1, OPC1) | \
131 ARM_CP15_REG_SHIFT_MASK(crn, 32_CRN) | \
132 ARM_CP15_REG_SHIFT_MASK(crm, CRM) | \
133 ARM_CP15_REG_SHIFT_MASK(op2, 32_OPC2))
134
135#define ARM_CP15_REG32(...) (__ARM_CP15_REG(__VA_ARGS__) | KVM_REG_SIZE_U32)
136
137#define __ARM_CP15_REG64(op1,crm) \
138 (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
139#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
140
141#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1)
142#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
143#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
144
145/* Normal registers are mapped as coprocessor 16. */
146#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
147#define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4)
148
149/* Some registers need more space to represent values. */
150#define KVM_REG_ARM_DEMUX (0x0011 << KVM_REG_ARM_COPROC_SHIFT)
151#define KVM_REG_ARM_DEMUX_ID_MASK 0x000000000000FF00
152#define KVM_REG_ARM_DEMUX_ID_SHIFT 8
153#define KVM_REG_ARM_DEMUX_ID_CCSIDR (0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
154#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00000000000000FF
155#define KVM_REG_ARM_DEMUX_VAL_SHIFT 0
156
157/* VFP registers: we could overload CP10 like ARM does, but that's ugly. */
158#define KVM_REG_ARM_VFP (0x0012 << KVM_REG_ARM_COPROC_SHIFT)
159#define KVM_REG_ARM_VFP_MASK 0x000000000000FFFF
160#define KVM_REG_ARM_VFP_BASE_REG 0x0
161#define KVM_REG_ARM_VFP_FPSID 0x1000
162#define KVM_REG_ARM_VFP_FPSCR 0x1001
163#define KVM_REG_ARM_VFP_MVFR1 0x1006
164#define KVM_REG_ARM_VFP_MVFR0 0x1007
165#define KVM_REG_ARM_VFP_FPEXC 0x1008
166#define KVM_REG_ARM_VFP_FPINST 0x1009
167#define KVM_REG_ARM_VFP_FPINST2 0x100A
168
169/* Device Control API: ARM VGIC */
170#define KVM_DEV_ARM_VGIC_GRP_ADDR 0
171#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
172#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
173#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
174#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
175#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
176#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
177#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
178#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
179#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
180
181/* KVM_IRQ_LINE irq field index values */
182#define KVM_ARM_IRQ_TYPE_SHIFT 24
183#define KVM_ARM_IRQ_TYPE_MASK 0xff
184#define KVM_ARM_IRQ_VCPU_SHIFT 16
185#define KVM_ARM_IRQ_VCPU_MASK 0xff
186#define KVM_ARM_IRQ_NUM_SHIFT 0
187#define KVM_ARM_IRQ_NUM_MASK 0xffff
188
189/* irq_type field */
190#define KVM_ARM_IRQ_TYPE_CPU 0
191#define KVM_ARM_IRQ_TYPE_SPI 1
192#define KVM_ARM_IRQ_TYPE_PPI 2
193
194/* out-of-kernel GIC cpu interrupt injection irq_number field */
195#define KVM_ARM_IRQ_CPU_IRQ 0
196#define KVM_ARM_IRQ_CPU_FIQ 1
197
198/*
199 * This used to hold the highest supported SPI, but it is now obsolete
200 * and only here to provide source code level compatibility with older
201 * userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS.
202 */
203#ifndef __KERNEL__
204#define KVM_ARM_IRQ_GIC_MAX 127
205#endif
206
207/* One single KVM irqchip, ie. the VGIC */
208#define KVM_NR_IRQCHIPS 1
209
210/* PSCI interface */
211#define KVM_PSCI_FN_BASE 0x95c1ba5e
212#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
213
214#define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0)
215#define KVM_PSCI_FN_CPU_OFF KVM_PSCI_FN(1)
216#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
217#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
218
219#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
220#define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
221#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
222#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
223
224#endif /* __ARM_KVM_H__ */
diff --git a/tools/arch/arm/include/uapi/asm/perf_regs.h b/tools/arch/arm/include/uapi/asm/perf_regs.h
new file mode 100644
index 000000000000..ce59448458b2
--- /dev/null
+++ b/tools/arch/arm/include/uapi/asm/perf_regs.h
@@ -0,0 +1,23 @@
1#ifndef _ASM_ARM_PERF_REGS_H
2#define _ASM_ARM_PERF_REGS_H
3
4enum perf_event_arm_regs {
5 PERF_REG_ARM_R0,
6 PERF_REG_ARM_R1,
7 PERF_REG_ARM_R2,
8 PERF_REG_ARM_R3,
9 PERF_REG_ARM_R4,
10 PERF_REG_ARM_R5,
11 PERF_REG_ARM_R6,
12 PERF_REG_ARM_R7,
13 PERF_REG_ARM_R8,
14 PERF_REG_ARM_R9,
15 PERF_REG_ARM_R10,
16 PERF_REG_ARM_FP,
17 PERF_REG_ARM_IP,
18 PERF_REG_ARM_SP,
19 PERF_REG_ARM_LR,
20 PERF_REG_ARM_PC,
21 PERF_REG_ARM_MAX,
22};
23#endif /* _ASM_ARM_PERF_REGS_H */
diff --git a/tools/arch/arm64/include/uapi/asm/bitsperlong.h b/tools/arch/arm64/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..fce9c2924fa3
--- /dev/null
+++ b/tools/arch/arm64/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_BITSPERLONG_H
17#define __ASM_BITSPERLONG_H
18
19#define __BITS_PER_LONG 64
20
21#include <asm-generic/bitsperlong.h>
22
23#endif /* __ASM_BITSPERLONG_H */
diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h
new file mode 100644
index 000000000000..f209ea151dca
--- /dev/null
+++ b/tools/arch/arm64/include/uapi/asm/kvm.h
@@ -0,0 +1,258 @@
1/*
2 * Copyright (C) 2012,2013 - ARM Ltd
3 * Author: Marc Zyngier <marc.zyngier@arm.com>
4 *
5 * Derived from arch/arm/include/uapi/asm/kvm.h:
6 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
7 * Author: Christoffer Dall <c.dall@virtualopensystems.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#ifndef __ARM_KVM_H__
23#define __ARM_KVM_H__
24
25#define KVM_SPSR_EL1 0
26#define KVM_SPSR_SVC KVM_SPSR_EL1
27#define KVM_SPSR_ABT 1
28#define KVM_SPSR_UND 2
29#define KVM_SPSR_IRQ 3
30#define KVM_SPSR_FIQ 4
31#define KVM_NR_SPSR 5
32
33#ifndef __ASSEMBLY__
34#include <linux/psci.h>
35#include <linux/types.h>
36#include <asm/ptrace.h>
37
38#define __KVM_HAVE_GUEST_DEBUG
39#define __KVM_HAVE_IRQ_LINE
40#define __KVM_HAVE_READONLY_MEM
41
42#define KVM_REG_SIZE(id) \
43 (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
44
45struct kvm_regs {
46 struct user_pt_regs regs; /* sp = sp_el0 */
47
48 __u64 sp_el1;
49 __u64 elr_el1;
50
51 __u64 spsr[KVM_NR_SPSR];
52
53 struct user_fpsimd_state fp_regs;
54};
55
56/*
57 * Supported CPU Targets - Adding a new target type is not recommended,
58 * unless there are some special registers not supported by the
59 * genericv8 syreg table.
60 */
61#define KVM_ARM_TARGET_AEM_V8 0
62#define KVM_ARM_TARGET_FOUNDATION_V8 1
63#define KVM_ARM_TARGET_CORTEX_A57 2
64#define KVM_ARM_TARGET_XGENE_POTENZA 3
65#define KVM_ARM_TARGET_CORTEX_A53 4
66/* Generic ARM v8 target */
67#define KVM_ARM_TARGET_GENERIC_V8 5
68
69#define KVM_ARM_NUM_TARGETS 6
70
71/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
72#define KVM_ARM_DEVICE_TYPE_SHIFT 0
73#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
74#define KVM_ARM_DEVICE_ID_SHIFT 16
75#define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT)
76
77/* Supported device IDs */
78#define KVM_ARM_DEVICE_VGIC_V2 0
79
80/* Supported VGIC address types */
81#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
82#define KVM_VGIC_V2_ADDR_TYPE_CPU 1
83
84#define KVM_VGIC_V2_DIST_SIZE 0x1000
85#define KVM_VGIC_V2_CPU_SIZE 0x2000
86
87/* Supported VGICv3 address types */
88#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
89#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
90
91#define KVM_VGIC_V3_DIST_SIZE SZ_64K
92#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
93
94#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
95#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
96#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
97#define KVM_ARM_VCPU_PMU_V3 3 /* Support guest PMUv3 */
98
99struct kvm_vcpu_init {
100 __u32 target;
101 __u32 features[7];
102};
103
104struct kvm_sregs {
105};
106
107struct kvm_fpu {
108};
109
110/*
111 * See v8 ARM ARM D7.3: Debug Registers
112 *
113 * The architectural limit is 16 debug registers of each type although
114 * in practice there are usually less (see ID_AA64DFR0_EL1).
115 *
116 * Although the control registers are architecturally defined as 32
117 * bits wide we use a 64 bit structure here to keep parity with
118 * KVM_GET/SET_ONE_REG behaviour which treats all system registers as
119 * 64 bit values. It also allows for the possibility of the
120 * architecture expanding the control registers without having to
121 * change the userspace ABI.
122 */
123#define KVM_ARM_MAX_DBG_REGS 16
124struct kvm_guest_debug_arch {
125 __u64 dbg_bcr[KVM_ARM_MAX_DBG_REGS];
126 __u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS];
127 __u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
128 __u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
129};
130
131struct kvm_debug_exit_arch {
132 __u32 hsr;
133 __u64 far; /* used for watchpoints */
134};
135
136/*
137 * Architecture specific defines for kvm_guest_debug->control
138 */
139
140#define KVM_GUESTDBG_USE_SW_BP (1 << 16)
141#define KVM_GUESTDBG_USE_HW (1 << 17)
142
143struct kvm_sync_regs {
144};
145
146struct kvm_arch_memory_slot {
147};
148
149/* If you need to interpret the index values, here is the key: */
150#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
151#define KVM_REG_ARM_COPROC_SHIFT 16
152
153/* Normal registers are mapped as coprocessor 16. */
154#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
155#define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / sizeof(__u32))
156
157/* Some registers need more space to represent values. */
158#define KVM_REG_ARM_DEMUX (0x0011 << KVM_REG_ARM_COPROC_SHIFT)
159#define KVM_REG_ARM_DEMUX_ID_MASK 0x000000000000FF00
160#define KVM_REG_ARM_DEMUX_ID_SHIFT 8
161#define KVM_REG_ARM_DEMUX_ID_CCSIDR (0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
162#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00000000000000FF
163#define KVM_REG_ARM_DEMUX_VAL_SHIFT 0
164
165/* AArch64 system registers */
166#define KVM_REG_ARM64_SYSREG (0x0013 << KVM_REG_ARM_COPROC_SHIFT)
167#define KVM_REG_ARM64_SYSREG_OP0_MASK 0x000000000000c000
168#define KVM_REG_ARM64_SYSREG_OP0_SHIFT 14
169#define KVM_REG_ARM64_SYSREG_OP1_MASK 0x0000000000003800
170#define KVM_REG_ARM64_SYSREG_OP1_SHIFT 11
171#define KVM_REG_ARM64_SYSREG_CRN_MASK 0x0000000000000780
172#define KVM_REG_ARM64_SYSREG_CRN_SHIFT 7
173#define KVM_REG_ARM64_SYSREG_CRM_MASK 0x0000000000000078
174#define KVM_REG_ARM64_SYSREG_CRM_SHIFT 3
175#define KVM_REG_ARM64_SYSREG_OP2_MASK 0x0000000000000007
176#define KVM_REG_ARM64_SYSREG_OP2_SHIFT 0
177
178#define ARM64_SYS_REG_SHIFT_MASK(x,n) \
179 (((x) << KVM_REG_ARM64_SYSREG_ ## n ## _SHIFT) & \
180 KVM_REG_ARM64_SYSREG_ ## n ## _MASK)
181
182#define __ARM64_SYS_REG(op0,op1,crn,crm,op2) \
183 (KVM_REG_ARM64 | KVM_REG_ARM64_SYSREG | \
184 ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | \
185 ARM64_SYS_REG_SHIFT_MASK(op1, OP1) | \
186 ARM64_SYS_REG_SHIFT_MASK(crn, CRN) | \
187 ARM64_SYS_REG_SHIFT_MASK(crm, CRM) | \
188 ARM64_SYS_REG_SHIFT_MASK(op2, OP2))
189
190#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64)
191
192#define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1)
193#define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)
194#define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2)
195
196/* Device Control API: ARM VGIC */
197#define KVM_DEV_ARM_VGIC_GRP_ADDR 0
198#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
199#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
200#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
201#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
202#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
203#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
204#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
205#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
206#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
207
208/* Device Control API on vcpu fd */
209#define KVM_ARM_VCPU_PMU_V3_CTRL 0
210#define KVM_ARM_VCPU_PMU_V3_IRQ 0
211#define KVM_ARM_VCPU_PMU_V3_INIT 1
212
213/* KVM_IRQ_LINE irq field index values */
214#define KVM_ARM_IRQ_TYPE_SHIFT 24
215#define KVM_ARM_IRQ_TYPE_MASK 0xff
216#define KVM_ARM_IRQ_VCPU_SHIFT 16
217#define KVM_ARM_IRQ_VCPU_MASK 0xff
218#define KVM_ARM_IRQ_NUM_SHIFT 0
219#define KVM_ARM_IRQ_NUM_MASK 0xffff
220
221/* irq_type field */
222#define KVM_ARM_IRQ_TYPE_CPU 0
223#define KVM_ARM_IRQ_TYPE_SPI 1
224#define KVM_ARM_IRQ_TYPE_PPI 2
225
226/* out-of-kernel GIC cpu interrupt injection irq_number field */
227#define KVM_ARM_IRQ_CPU_IRQ 0
228#define KVM_ARM_IRQ_CPU_FIQ 1
229
230/*
231 * This used to hold the highest supported SPI, but it is now obsolete
232 * and only here to provide source code level compatibility with older
233 * userland. The highest SPI number can be set via KVM_DEV_ARM_VGIC_GRP_NR_IRQS.
234 */
235#ifndef __KERNEL__
236#define KVM_ARM_IRQ_GIC_MAX 127
237#endif
238
239/* One single KVM irqchip, ie. the VGIC */
240#define KVM_NR_IRQCHIPS 1
241
242/* PSCI interface */
243#define KVM_PSCI_FN_BASE 0x95c1ba5e
244#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
245
246#define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0)
247#define KVM_PSCI_FN_CPU_OFF KVM_PSCI_FN(1)
248#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
249#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
250
251#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
252#define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
253#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
254#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
255
256#endif
257
258#endif /* __ARM_KVM_H__ */
diff --git a/tools/arch/arm64/include/uapi/asm/perf_regs.h b/tools/arch/arm64/include/uapi/asm/perf_regs.h
new file mode 100644
index 000000000000..172b8317ee49
--- /dev/null
+++ b/tools/arch/arm64/include/uapi/asm/perf_regs.h
@@ -0,0 +1,40 @@
1#ifndef _ASM_ARM64_PERF_REGS_H
2#define _ASM_ARM64_PERF_REGS_H
3
4enum perf_event_arm_regs {
5 PERF_REG_ARM64_X0,
6 PERF_REG_ARM64_X1,
7 PERF_REG_ARM64_X2,
8 PERF_REG_ARM64_X3,
9 PERF_REG_ARM64_X4,
10 PERF_REG_ARM64_X5,
11 PERF_REG_ARM64_X6,
12 PERF_REG_ARM64_X7,
13 PERF_REG_ARM64_X8,
14 PERF_REG_ARM64_X9,
15 PERF_REG_ARM64_X10,
16 PERF_REG_ARM64_X11,
17 PERF_REG_ARM64_X12,
18 PERF_REG_ARM64_X13,
19 PERF_REG_ARM64_X14,
20 PERF_REG_ARM64_X15,
21 PERF_REG_ARM64_X16,
22 PERF_REG_ARM64_X17,
23 PERF_REG_ARM64_X18,
24 PERF_REG_ARM64_X19,
25 PERF_REG_ARM64_X20,
26 PERF_REG_ARM64_X21,
27 PERF_REG_ARM64_X22,
28 PERF_REG_ARM64_X23,
29 PERF_REG_ARM64_X24,
30 PERF_REG_ARM64_X25,
31 PERF_REG_ARM64_X26,
32 PERF_REG_ARM64_X27,
33 PERF_REG_ARM64_X28,
34 PERF_REG_ARM64_X29,
35 PERF_REG_ARM64_LR,
36 PERF_REG_ARM64_SP,
37 PERF_REG_ARM64_PC,
38 PERF_REG_ARM64_MAX,
39};
40#endif /* _ASM_ARM64_PERF_REGS_H */
diff --git a/tools/arch/frv/include/uapi/asm/bitsperlong.h b/tools/arch/frv/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..6dc0bb0c13b2
--- /dev/null
+++ b/tools/arch/frv/include/uapi/asm/bitsperlong.h
@@ -0,0 +1 @@
#include <asm-generic/bitsperlong.h>
diff --git a/tools/arch/h8300/include/asm/bitsperlong.h b/tools/arch/h8300/include/asm/bitsperlong.h
new file mode 100644
index 000000000000..e140e46729ac
--- /dev/null
+++ b/tools/arch/h8300/include/asm/bitsperlong.h
@@ -0,0 +1,14 @@
1#ifndef __ASM_H8300_BITS_PER_LONG
2#define __ASM_H8300_BITS_PER_LONG
3
4#include <asm-generic/bitsperlong.h>
5
6#if !defined(__ASSEMBLY__)
7/* h8300-unknown-linux required long */
8#define __kernel_size_t __kernel_size_t
9typedef unsigned long __kernel_size_t;
10typedef long __kernel_ssize_t;
11typedef long __kernel_ptrdiff_t;
12#endif
13
14#endif /* __ASM_H8300_BITS_PER_LONG */
diff --git a/tools/arch/hexagon/include/uapi/asm/bitsperlong.h b/tools/arch/hexagon/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..4a658151383d
--- /dev/null
+++ b/tools/arch/hexagon/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301, USA.
17 */
18
19#ifndef __ASM_HEXAGON_BITSPERLONG_H
20#define __ASM_HEXAGON_BITSPERLONG_H
21
22#define __BITS_PER_LONG 32
23
24#include <asm-generic/bitsperlong.h>
25
26#endif
diff --git a/tools/arch/ia64/include/uapi/asm/bitsperlong.h b/tools/arch/ia64/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..ec4db3c970b7
--- /dev/null
+++ b/tools/arch/ia64/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,8 @@
1#ifndef __ASM_IA64_BITSPERLONG_H
2#define __ASM_IA64_BITSPERLONG_H
3
4#define __BITS_PER_LONG 64
5
6#include <asm-generic/bitsperlong.h>
7
8#endif /* __ASM_IA64_BITSPERLONG_H */
diff --git a/tools/arch/m32r/include/uapi/asm/bitsperlong.h b/tools/arch/m32r/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..6dc0bb0c13b2
--- /dev/null
+++ b/tools/arch/m32r/include/uapi/asm/bitsperlong.h
@@ -0,0 +1 @@
#include <asm-generic/bitsperlong.h>
diff --git a/tools/arch/microblaze/include/uapi/asm/bitsperlong.h b/tools/arch/microblaze/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..6dc0bb0c13b2
--- /dev/null
+++ b/tools/arch/microblaze/include/uapi/asm/bitsperlong.h
@@ -0,0 +1 @@
#include <asm-generic/bitsperlong.h>
diff --git a/tools/arch/mips/include/uapi/asm/bitsperlong.h b/tools/arch/mips/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..3e4c10a8e787
--- /dev/null
+++ b/tools/arch/mips/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,8 @@
1#ifndef __ASM_MIPS_BITSPERLONG_H
2#define __ASM_MIPS_BITSPERLONG_H
3
4#define __BITS_PER_LONG _MIPS_SZLONG
5
6#include <asm-generic/bitsperlong.h>
7
8#endif /* __ASM_MIPS_BITSPERLONG_H */
diff --git a/tools/arch/mips/include/uapi/asm/kvm.h b/tools/arch/mips/include/uapi/asm/kvm.h
new file mode 100644
index 000000000000..6985eb59b085
--- /dev/null
+++ b/tools/arch/mips/include/uapi/asm/kvm.h
@@ -0,0 +1,208 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 * Copyright (C) 2013 Cavium, Inc.
8 * Authors: Sanjay Lal <sanjayl@kymasys.com>
9 */
10
11#ifndef __LINUX_KVM_MIPS_H
12#define __LINUX_KVM_MIPS_H
13
14#include <linux/types.h>
15
16/*
17 * KVM MIPS specific structures and definitions.
18 *
19 * Some parts derived from the x86 version of this file.
20 */
21
22/*
23 * for KVM_GET_REGS and KVM_SET_REGS
24 *
25 * If Config[AT] is zero (32-bit CPU), the register contents are
26 * stored in the lower 32-bits of the struct kvm_regs fields and sign
27 * extended to 64-bits.
28 */
29struct kvm_regs {
30 /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
31 __u64 gpr[32];
32 __u64 hi;
33 __u64 lo;
34 __u64 pc;
35};
36
37/*
38 * for KVM_GET_FPU and KVM_SET_FPU
39 */
40struct kvm_fpu {
41};
42
43
44/*
45 * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various
46 * registers. The id field is broken down as follows:
47 *
48 * bits[63..52] - As per linux/kvm.h
49 * bits[51..32] - Must be zero.
50 * bits[31..16] - Register set.
51 *
52 * Register set = 0: GP registers from kvm_regs (see definitions below).
53 *
54 * Register set = 1: CP0 registers.
55 * bits[15..8] - Must be zero.
56 * bits[7..3] - Register 'rd' index.
57 * bits[2..0] - Register 'sel' index.
58 *
59 * Register set = 2: KVM specific registers (see definitions below).
60 *
61 * Register set = 3: FPU / MSA registers (see definitions below).
62 *
63 * Other sets registers may be added in the future. Each set would
64 * have its own identifier in bits[31..16].
65 */
66
67#define KVM_REG_MIPS_GP (KVM_REG_MIPS | 0x0000000000000000ULL)
68#define KVM_REG_MIPS_CP0 (KVM_REG_MIPS | 0x0000000000010000ULL)
69#define KVM_REG_MIPS_KVM (KVM_REG_MIPS | 0x0000000000020000ULL)
70#define KVM_REG_MIPS_FPU (KVM_REG_MIPS | 0x0000000000030000ULL)
71
72
73/*
74 * KVM_REG_MIPS_GP - General purpose registers from kvm_regs.
75 */
76
77#define KVM_REG_MIPS_R0 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 0)
78#define KVM_REG_MIPS_R1 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 1)
79#define KVM_REG_MIPS_R2 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 2)
80#define KVM_REG_MIPS_R3 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 3)
81#define KVM_REG_MIPS_R4 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 4)
82#define KVM_REG_MIPS_R5 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 5)
83#define KVM_REG_MIPS_R6 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 6)
84#define KVM_REG_MIPS_R7 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 7)
85#define KVM_REG_MIPS_R8 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 8)
86#define KVM_REG_MIPS_R9 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 9)
87#define KVM_REG_MIPS_R10 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 10)
88#define KVM_REG_MIPS_R11 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 11)
89#define KVM_REG_MIPS_R12 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 12)
90#define KVM_REG_MIPS_R13 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 13)
91#define KVM_REG_MIPS_R14 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 14)
92#define KVM_REG_MIPS_R15 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 15)
93#define KVM_REG_MIPS_R16 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 16)
94#define KVM_REG_MIPS_R17 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 17)
95#define KVM_REG_MIPS_R18 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 18)
96#define KVM_REG_MIPS_R19 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 19)
97#define KVM_REG_MIPS_R20 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 20)
98#define KVM_REG_MIPS_R21 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 21)
99#define KVM_REG_MIPS_R22 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 22)
100#define KVM_REG_MIPS_R23 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 23)
101#define KVM_REG_MIPS_R24 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 24)
102#define KVM_REG_MIPS_R25 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 25)
103#define KVM_REG_MIPS_R26 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 26)
104#define KVM_REG_MIPS_R27 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 27)
105#define KVM_REG_MIPS_R28 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 28)
106#define KVM_REG_MIPS_R29 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 29)
107#define KVM_REG_MIPS_R30 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 30)
108#define KVM_REG_MIPS_R31 (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 31)
109
110#define KVM_REG_MIPS_HI (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 32)
111#define KVM_REG_MIPS_LO (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 33)
112#define KVM_REG_MIPS_PC (KVM_REG_MIPS_GP | KVM_REG_SIZE_U64 | 34)
113
114
115/*
116 * KVM_REG_MIPS_KVM - KVM specific control registers.
117 */
118
119/*
120 * CP0_Count control
121 * DC: Set 0: Master disable CP0_Count and set COUNT_RESUME to now
122 * Set 1: Master re-enable CP0_Count with unchanged bias, handling timer
123 * interrupts since COUNT_RESUME
124 * This can be used to freeze the timer to get a consistent snapshot of
125 * the CP0_Count and timer interrupt pending state, while also resuming
126 * safely without losing time or guest timer interrupts.
127 * Other: Reserved, do not change.
128 */
129#define KVM_REG_MIPS_COUNT_CTL (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 0)
130#define KVM_REG_MIPS_COUNT_CTL_DC 0x00000001
131
132/*
133 * CP0_Count resume monotonic nanoseconds
134 * The monotonic nanosecond time of the last set of COUNT_CTL.DC (master
135 * disable). Any reads and writes of Count related registers while
136 * COUNT_CTL.DC=1 will appear to occur at this time. When COUNT_CTL.DC is
137 * cleared again (master enable) any timer interrupts since this time will be
138 * emulated.
139 * Modifications to times in the future are rejected.
140 */
141#define KVM_REG_MIPS_COUNT_RESUME (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 1)
142/*
143 * CP0_Count rate in Hz
144 * Specifies the rate of the CP0_Count timer in Hz. Modifications occur without
145 * discontinuities in CP0_Count.
146 */
147#define KVM_REG_MIPS_COUNT_HZ (KVM_REG_MIPS_KVM | KVM_REG_SIZE_U64 | 2)
148
149
150/*
151 * KVM_REG_MIPS_FPU - Floating Point and MIPS SIMD Architecture (MSA) registers.
152 *
153 * bits[15..8] - Register subset (see definitions below).
154 * bits[7..5] - Must be zero.
155 * bits[4..0] - Register number within register subset.
156 */
157
158#define KVM_REG_MIPS_FPR (KVM_REG_MIPS_FPU | 0x0000000000000000ULL)
159#define KVM_REG_MIPS_FCR (KVM_REG_MIPS_FPU | 0x0000000000000100ULL)
160#define KVM_REG_MIPS_MSACR (KVM_REG_MIPS_FPU | 0x0000000000000200ULL)
161
162/*
163 * KVM_REG_MIPS_FPR - Floating point / Vector registers.
164 */
165#define KVM_REG_MIPS_FPR_32(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U32 | (n))
166#define KVM_REG_MIPS_FPR_64(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U64 | (n))
167#define KVM_REG_MIPS_VEC_128(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U128 | (n))
168
169/*
170 * KVM_REG_MIPS_FCR - Floating point control registers.
171 */
172#define KVM_REG_MIPS_FCR_IR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 0)
173#define KVM_REG_MIPS_FCR_CSR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 31)
174
175/*
176 * KVM_REG_MIPS_MSACR - MIPS SIMD Architecture (MSA) control registers.
177 */
178#define KVM_REG_MIPS_MSA_IR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 | 0)
179#define KVM_REG_MIPS_MSA_CSR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 | 1)
180
181
182/*
183 * KVM MIPS specific structures and definitions
184 *
185 */
186struct kvm_debug_exit_arch {
187 __u64 epc;
188};
189
190/* for KVM_SET_GUEST_DEBUG */
191struct kvm_guest_debug_arch {
192};
193
194/* definition of registers in kvm_run */
195struct kvm_sync_regs {
196};
197
198/* dummy definition */
199struct kvm_sregs {
200};
201
202struct kvm_mips_interrupt {
203 /* in */
204 __u32 cpu;
205 __u32 irq;
206};
207
208#endif /* __LINUX_KVM_MIPS_H */
diff --git a/tools/arch/mn10300/include/uapi/asm/bitsperlong.h b/tools/arch/mn10300/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..6dc0bb0c13b2
--- /dev/null
+++ b/tools/arch/mn10300/include/uapi/asm/bitsperlong.h
@@ -0,0 +1 @@
#include <asm-generic/bitsperlong.h>
diff --git a/tools/arch/parisc/include/uapi/asm/bitsperlong.h b/tools/arch/parisc/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..e0a23c7bdd43
--- /dev/null
+++ b/tools/arch/parisc/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,14 @@
1#ifndef __ASM_PARISC_BITSPERLONG_H
2#define __ASM_PARISC_BITSPERLONG_H
3
4#if defined(__LP64__)
5#define __BITS_PER_LONG 64
6#define SHIFT_PER_LONG 6
7#else
8#define __BITS_PER_LONG 32
9#define SHIFT_PER_LONG 5
10#endif
11
12#include <asm-generic/bitsperlong.h>
13
14#endif /* __ASM_PARISC_BITSPERLONG_H */
diff --git a/tools/arch/powerpc/include/uapi/asm/bitsperlong.h b/tools/arch/powerpc/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..5f1659032c40
--- /dev/null
+++ b/tools/arch/powerpc/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,12 @@
1#ifndef __ASM_POWERPC_BITSPERLONG_H
2#define __ASM_POWERPC_BITSPERLONG_H
3
4#if defined(__powerpc64__)
5# define __BITS_PER_LONG 64
6#else
7# define __BITS_PER_LONG 32
8#endif
9
10#include <asm-generic/bitsperlong.h>
11
12#endif /* __ASM_POWERPC_BITSPERLONG_H */
diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h
new file mode 100644
index 000000000000..c93cf35ce379
--- /dev/null
+++ b/tools/arch/powerpc/include/uapi/asm/kvm.h
@@ -0,0 +1,612 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 */
19
20#ifndef __LINUX_KVM_POWERPC_H
21#define __LINUX_KVM_POWERPC_H
22
23#include <linux/types.h>
24
25/* Select powerpc specific features in <linux/kvm.h> */
26#define __KVM_HAVE_SPAPR_TCE
27#define __KVM_HAVE_PPC_SMT
28#define __KVM_HAVE_IRQCHIP
29#define __KVM_HAVE_IRQ_LINE
30#define __KVM_HAVE_GUEST_DEBUG
31
32struct kvm_regs {
33 __u64 pc;
34 __u64 cr;
35 __u64 ctr;
36 __u64 lr;
37 __u64 xer;
38 __u64 msr;
39 __u64 srr0;
40 __u64 srr1;
41 __u64 pid;
42
43 __u64 sprg0;
44 __u64 sprg1;
45 __u64 sprg2;
46 __u64 sprg3;
47 __u64 sprg4;
48 __u64 sprg5;
49 __u64 sprg6;
50 __u64 sprg7;
51
52 __u64 gpr[32];
53};
54
55#define KVM_SREGS_E_IMPL_NONE 0
56#define KVM_SREGS_E_IMPL_FSL 1
57
58#define KVM_SREGS_E_FSL_PIDn (1 << 0) /* PID1/PID2 */
59
60/*
61 * Feature bits indicate which sections of the sregs struct are valid,
62 * both in KVM_GET_SREGS and KVM_SET_SREGS. On KVM_SET_SREGS, registers
63 * corresponding to unset feature bits will not be modified. This allows
64 * restoring a checkpoint made without that feature, while keeping the
65 * default values of the new registers.
66 *
67 * KVM_SREGS_E_BASE contains:
68 * CSRR0/1 (refers to SRR2/3 on 40x)
69 * ESR
70 * DEAR
71 * MCSR
72 * TSR
73 * TCR
74 * DEC
75 * TB
76 * VRSAVE (USPRG0)
77 */
78#define KVM_SREGS_E_BASE (1 << 0)
79
80/*
81 * KVM_SREGS_E_ARCH206 contains:
82 *
83 * PIR
84 * MCSRR0/1
85 * DECAR
86 * IVPR
87 */
88#define KVM_SREGS_E_ARCH206 (1 << 1)
89
90/*
91 * Contains EPCR, plus the upper half of 64-bit registers
92 * that are 32-bit on 32-bit implementations.
93 */
94#define KVM_SREGS_E_64 (1 << 2)
95
96#define KVM_SREGS_E_SPRG8 (1 << 3)
97#define KVM_SREGS_E_MCIVPR (1 << 4)
98
99/*
100 * IVORs are used -- contains IVOR0-15, plus additional IVORs
101 * in combination with an appropriate feature bit.
102 */
103#define KVM_SREGS_E_IVOR (1 << 5)
104
105/*
106 * Contains MAS0-4, MAS6-7, TLBnCFG, MMUCFG.
107 * Also TLBnPS if MMUCFG[MAVN] = 1.
108 */
109#define KVM_SREGS_E_ARCH206_MMU (1 << 6)
110
111/* DBSR, DBCR, IAC, DAC, DVC */
112#define KVM_SREGS_E_DEBUG (1 << 7)
113
114/* Enhanced debug -- DSRR0/1, SPRG9 */
115#define KVM_SREGS_E_ED (1 << 8)
116
117/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
118#define KVM_SREGS_E_SPE (1 << 9)
119
120/*
121 * DEPRECATED! USE ONE_REG FOR THIS ONE!
122 * External Proxy (EXP) -- EPR
123 */
124#define KVM_SREGS_EXP (1 << 10)
125
126/* External PID (E.PD) -- EPSC/EPLC */
127#define KVM_SREGS_E_PD (1 << 11)
128
129/* Processor Control (E.PC) -- IVOR36-37 if KVM_SREGS_E_IVOR */
130#define KVM_SREGS_E_PC (1 << 12)
131
132/* Page table (E.PT) -- EPTCFG */
133#define KVM_SREGS_E_PT (1 << 13)
134
135/* Embedded Performance Monitor (E.PM) -- IVOR35 if KVM_SREGS_E_IVOR */
136#define KVM_SREGS_E_PM (1 << 14)
137
138/*
139 * Special updates:
140 *
141 * Some registers may change even while a vcpu is not running.
142 * To avoid losing these changes, by default these registers are
143 * not updated by KVM_SET_SREGS. To force an update, set the bit
144 * in u.e.update_special corresponding to the register to be updated.
145 *
146 * The update_special field is zero on return from KVM_GET_SREGS.
147 *
148 * When restoring a checkpoint, the caller can set update_special
149 * to 0xffffffff to ensure that everything is restored, even new features
150 * that the caller doesn't know about.
151 */
152#define KVM_SREGS_E_UPDATE_MCSR (1 << 0)
153#define KVM_SREGS_E_UPDATE_TSR (1 << 1)
154#define KVM_SREGS_E_UPDATE_DEC (1 << 2)
155#define KVM_SREGS_E_UPDATE_DBSR (1 << 3)
156
157/*
158 * In KVM_SET_SREGS, reserved/pad fields must be left untouched from a
159 * previous KVM_GET_REGS.
160 *
161 * Unless otherwise indicated, setting any register with KVM_SET_SREGS
162 * directly sets its value. It does not trigger any special semantics such
163 * as write-one-to-clear. Calling KVM_SET_SREGS on an unmodified struct
164 * just received from KVM_GET_SREGS is always a no-op.
165 */
166struct kvm_sregs {
167 __u32 pvr;
168 union {
169 struct {
170 __u64 sdr1;
171 struct {
172 struct {
173 __u64 slbe;
174 __u64 slbv;
175 } slb[64];
176 } ppc64;
177 struct {
178 __u32 sr[16];
179 __u64 ibat[8];
180 __u64 dbat[8];
181 } ppc32;
182 } s;
183 struct {
184 union {
185 struct { /* KVM_SREGS_E_IMPL_FSL */
186 __u32 features; /* KVM_SREGS_E_FSL_ */
187 __u32 svr;
188 __u64 mcar;
189 __u32 hid0;
190
191 /* KVM_SREGS_E_FSL_PIDn */
192 __u32 pid1, pid2;
193 } fsl;
194 __u8 pad[256];
195 } impl;
196
197 __u32 features; /* KVM_SREGS_E_ */
198 __u32 impl_id; /* KVM_SREGS_E_IMPL_ */
199 __u32 update_special; /* KVM_SREGS_E_UPDATE_ */
200 __u32 pir; /* read-only */
201 __u64 sprg8;
202 __u64 sprg9; /* E.ED */
203 __u64 csrr0;
204 __u64 dsrr0; /* E.ED */
205 __u64 mcsrr0;
206 __u32 csrr1;
207 __u32 dsrr1; /* E.ED */
208 __u32 mcsrr1;
209 __u32 esr;
210 __u64 dear;
211 __u64 ivpr;
212 __u64 mcivpr;
213 __u64 mcsr; /* KVM_SREGS_E_UPDATE_MCSR */
214
215 __u32 tsr; /* KVM_SREGS_E_UPDATE_TSR */
216 __u32 tcr;
217 __u32 decar;
218 __u32 dec; /* KVM_SREGS_E_UPDATE_DEC */
219
220 /*
221 * Userspace can read TB directly, but the
222 * value reported here is consistent with "dec".
223 *
224 * Read-only.
225 */
226 __u64 tb;
227
228 __u32 dbsr; /* KVM_SREGS_E_UPDATE_DBSR */
229 __u32 dbcr[3];
230 /*
231 * iac/dac registers are 64bit wide, while this API
232 * interface provides only lower 32 bits on 64 bit
233 * processors. ONE_REG interface is added for 64bit
234 * iac/dac registers.
235 */
236 __u32 iac[4];
237 __u32 dac[2];
238 __u32 dvc[2];
239 __u8 num_iac; /* read-only */
240 __u8 num_dac; /* read-only */
241 __u8 num_dvc; /* read-only */
242 __u8 pad;
243
244 __u32 epr; /* EXP */
245 __u32 vrsave; /* a.k.a. USPRG0 */
246 __u32 epcr; /* KVM_SREGS_E_64 */
247
248 __u32 mas0;
249 __u32 mas1;
250 __u64 mas2;
251 __u64 mas7_3;
252 __u32 mas4;
253 __u32 mas6;
254
255 __u32 ivor_low[16]; /* IVOR0-15 */
256 __u32 ivor_high[18]; /* IVOR32+, plus room to expand */
257
258 __u32 mmucfg; /* read-only */
259 __u32 eptcfg; /* E.PT, read-only */
260 __u32 tlbcfg[4];/* read-only */
261 __u32 tlbps[4]; /* read-only */
262
263 __u32 eplc, epsc; /* E.PD */
264 } e;
265 __u8 pad[1020];
266 } u;
267};
268
269struct kvm_fpu {
270 __u64 fpr[32];
271};
272
273/*
274 * Defines for h/w breakpoint, watchpoint (read, write or both) and
275 * software breakpoint.
276 * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and "status"
277 * for KVM_DEBUG_EXIT.
278 */
279#define KVMPPC_DEBUG_NONE 0x0
280#define KVMPPC_DEBUG_BREAKPOINT (1UL << 1)
281#define KVMPPC_DEBUG_WATCH_WRITE (1UL << 2)
282#define KVMPPC_DEBUG_WATCH_READ (1UL << 3)
283struct kvm_debug_exit_arch {
284 __u64 address;
285 /*
286 * exiting to userspace because of h/w breakpoint, watchpoint
287 * (read, write or both) and software breakpoint.
288 */
289 __u32 status;
290 __u32 reserved;
291};
292
293/* for KVM_SET_GUEST_DEBUG */
294struct kvm_guest_debug_arch {
295 struct {
296 /* H/W breakpoint/watchpoint address */
297 __u64 addr;
298 /*
299 * Type denotes h/w breakpoint, read watchpoint, write
300 * watchpoint or watchpoint (both read and write).
301 */
302 __u32 type;
303 __u32 reserved;
304 } bp[16];
305};
306
307/* Debug related defines */
308/*
309 * kvm_guest_debug->control is a 32 bit field. The lower 16 bits are generic
310 * and upper 16 bits are architecture specific. Architecture specific defines
311 * that ioctl is for setting hardware breakpoint or software breakpoint.
312 */
313#define KVM_GUESTDBG_USE_SW_BP 0x00010000
314#define KVM_GUESTDBG_USE_HW_BP 0x00020000
315
316/* definition of registers in kvm_run */
317struct kvm_sync_regs {
318};
319
320#define KVM_INTERRUPT_SET -1U
321#define KVM_INTERRUPT_UNSET -2U
322#define KVM_INTERRUPT_SET_LEVEL -3U
323
324#define KVM_CPU_440 1
325#define KVM_CPU_E500V2 2
326#define KVM_CPU_3S_32 3
327#define KVM_CPU_3S_64 4
328#define KVM_CPU_E500MC 5
329
330/* for KVM_CAP_SPAPR_TCE */
331struct kvm_create_spapr_tce {
332 __u64 liobn;
333 __u32 window_size;
334};
335
336/* for KVM_CAP_SPAPR_TCE_64 */
337struct kvm_create_spapr_tce_64 {
338 __u64 liobn;
339 __u32 page_shift;
340 __u32 flags;
341 __u64 offset; /* in pages */
342 __u64 size; /* in pages */
343};
344
345/* for KVM_ALLOCATE_RMA */
346struct kvm_allocate_rma {
347 __u64 rma_size;
348};
349
350/* for KVM_CAP_PPC_RTAS */
351struct kvm_rtas_token_args {
352 char name[120];
353 __u64 token; /* Use a token of 0 to undefine a mapping */
354};
355
356struct kvm_book3e_206_tlb_entry {
357 __u32 mas8;
358 __u32 mas1;
359 __u64 mas2;
360 __u64 mas7_3;
361};
362
363struct kvm_book3e_206_tlb_params {
364 /*
365 * For mmu types KVM_MMU_FSL_BOOKE_NOHV and KVM_MMU_FSL_BOOKE_HV:
366 *
367 * - The number of ways of TLB0 must be a power of two between 2 and
368 * 16.
369 * - TLB1 must be fully associative.
370 * - The size of TLB0 must be a multiple of the number of ways, and
371 * the number of sets must be a power of two.
372 * - The size of TLB1 may not exceed 64 entries.
373 * - TLB0 supports 4 KiB pages.
374 * - The page sizes supported by TLB1 are as indicated by
375 * TLB1CFG (if MMUCFG[MAVN] = 0) or TLB1PS (if MMUCFG[MAVN] = 1)
376 * as returned by KVM_GET_SREGS.
377 * - TLB2 and TLB3 are reserved, and their entries in tlb_sizes[]
378 * and tlb_ways[] must be zero.
379 *
380 * tlb_ways[n] = tlb_sizes[n] means the array is fully associative.
381 *
382 * KVM will adjust TLBnCFG based on the sizes configured here,
383 * though arrays greater than 2048 entries will have TLBnCFG[NENTRY]
384 * set to zero.
385 */
386 __u32 tlb_sizes[4];
387 __u32 tlb_ways[4];
388 __u32 reserved[8];
389};
390
391/* For KVM_PPC_GET_HTAB_FD */
392struct kvm_get_htab_fd {
393 __u64 flags;
394 __u64 start_index;
395 __u64 reserved[2];
396};
397
398/* Values for kvm_get_htab_fd.flags */
399#define KVM_GET_HTAB_BOLTED_ONLY ((__u64)0x1)
400#define KVM_GET_HTAB_WRITE ((__u64)0x2)
401
402/*
403 * Data read on the file descriptor is formatted as a series of
404 * records, each consisting of a header followed by a series of
405 * `n_valid' HPTEs (16 bytes each), which are all valid. Following
406 * those valid HPTEs there are `n_invalid' invalid HPTEs, which
407 * are not represented explicitly in the stream. The same format
408 * is used for writing.
409 */
410struct kvm_get_htab_header {
411 __u32 index;
412 __u16 n_valid;
413 __u16 n_invalid;
414};
415
416/* Per-vcpu XICS interrupt controller state */
417#define KVM_REG_PPC_ICP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
418
419#define KVM_REG_PPC_ICP_CPPR_SHIFT 56 /* current proc priority */
420#define KVM_REG_PPC_ICP_CPPR_MASK 0xff
421#define KVM_REG_PPC_ICP_XISR_SHIFT 32 /* interrupt status field */
422#define KVM_REG_PPC_ICP_XISR_MASK 0xffffff
423#define KVM_REG_PPC_ICP_MFRR_SHIFT 24 /* pending IPI priority */
424#define KVM_REG_PPC_ICP_MFRR_MASK 0xff
425#define KVM_REG_PPC_ICP_PPRI_SHIFT 16 /* pending irq priority */
426#define KVM_REG_PPC_ICP_PPRI_MASK 0xff
427
428/* Device control API: PPC-specific devices */
429#define KVM_DEV_MPIC_GRP_MISC 1
430#define KVM_DEV_MPIC_BASE_ADDR 0 /* 64-bit */
431
432#define KVM_DEV_MPIC_GRP_REGISTER 2 /* 32-bit */
433#define KVM_DEV_MPIC_GRP_IRQ_ACTIVE 3 /* 32-bit */
434
435/* One-Reg API: PPC-specific registers */
436#define KVM_REG_PPC_HIOR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
437#define KVM_REG_PPC_IAC1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
438#define KVM_REG_PPC_IAC2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
439#define KVM_REG_PPC_IAC3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4)
440#define KVM_REG_PPC_IAC4 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5)
441#define KVM_REG_PPC_DAC1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6)
442#define KVM_REG_PPC_DAC2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7)
443#define KVM_REG_PPC_DABR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8)
444#define KVM_REG_PPC_DSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9)
445#define KVM_REG_PPC_PURR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa)
446#define KVM_REG_PPC_SPURR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb)
447#define KVM_REG_PPC_DAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc)
448#define KVM_REG_PPC_DSISR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xd)
449#define KVM_REG_PPC_AMR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xe)
450#define KVM_REG_PPC_UAMOR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xf)
451
452#define KVM_REG_PPC_MMCR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x10)
453#define KVM_REG_PPC_MMCR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x11)
454#define KVM_REG_PPC_MMCRA (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x12)
455#define KVM_REG_PPC_MMCR2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x13)
456#define KVM_REG_PPC_MMCRS (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x14)
457#define KVM_REG_PPC_SIAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x15)
458#define KVM_REG_PPC_SDAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x16)
459#define KVM_REG_PPC_SIER (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x17)
460
461#define KVM_REG_PPC_PMC1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x18)
462#define KVM_REG_PPC_PMC2 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x19)
463#define KVM_REG_PPC_PMC3 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1a)
464#define KVM_REG_PPC_PMC4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1b)
465#define KVM_REG_PPC_PMC5 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1c)
466#define KVM_REG_PPC_PMC6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1d)
467#define KVM_REG_PPC_PMC7 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1e)
468#define KVM_REG_PPC_PMC8 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1f)
469
470/* 32 floating-point registers */
471#define KVM_REG_PPC_FPR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x20)
472#define KVM_REG_PPC_FPR(n) (KVM_REG_PPC_FPR0 + (n))
473#define KVM_REG_PPC_FPR31 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3f)
474
475/* 32 VMX/Altivec vector registers */
476#define KVM_REG_PPC_VR0 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x40)
477#define KVM_REG_PPC_VR(n) (KVM_REG_PPC_VR0 + (n))
478#define KVM_REG_PPC_VR31 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x5f)
479
480/* 32 double-width FP registers for VSX */
481/* High-order halves overlap with FP regs */
482#define KVM_REG_PPC_VSR0 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x60)
483#define KVM_REG_PPC_VSR(n) (KVM_REG_PPC_VSR0 + (n))
484#define KVM_REG_PPC_VSR31 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x7f)
485
486/* FP and vector status/control registers */
487#define KVM_REG_PPC_FPSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x80)
488/*
489 * VSCR register is documented as a 32-bit register in the ISA, but it can
490 * only be accesses via a vector register. Expose VSCR as a 32-bit register
491 * even though the kernel represents it as a 128-bit vector.
492 */
493#define KVM_REG_PPC_VSCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x81)
494
495/* Virtual processor areas */
496/* For SLB & DTL, address in high (first) half, length in low half */
497#define KVM_REG_PPC_VPA_ADDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x82)
498#define KVM_REG_PPC_VPA_SLB (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x83)
499#define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
500
501#define KVM_REG_PPC_EPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
502#define KVM_REG_PPC_EPR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
503
504/* Timer Status Register OR/CLEAR interface */
505#define KVM_REG_PPC_OR_TSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x87)
506#define KVM_REG_PPC_CLEAR_TSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x88)
507#define KVM_REG_PPC_TCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x89)
508#define KVM_REG_PPC_TSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8a)
509
510/* Debugging: Special instruction for software breakpoint */
511#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8b)
512
513/* MMU registers */
514#define KVM_REG_PPC_MAS0 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8c)
515#define KVM_REG_PPC_MAS1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x8d)
516#define KVM_REG_PPC_MAS2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8e)
517#define KVM_REG_PPC_MAS7_3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8f)
518#define KVM_REG_PPC_MAS4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x90)
519#define KVM_REG_PPC_MAS6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x91)
520#define KVM_REG_PPC_MMUCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x92)
521/*
522 * TLBnCFG fields TLBnCFG_N_ENTRY and TLBnCFG_ASSOC can be changed only using
523 * KVM_CAP_SW_TLB ioctl
524 */
525#define KVM_REG_PPC_TLB0CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x93)
526#define KVM_REG_PPC_TLB1CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x94)
527#define KVM_REG_PPC_TLB2CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x95)
528#define KVM_REG_PPC_TLB3CFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x96)
529#define KVM_REG_PPC_TLB0PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x97)
530#define KVM_REG_PPC_TLB1PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x98)
531#define KVM_REG_PPC_TLB2PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x99)
532#define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
533#define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b)
534
535/* Timebase offset */
536#define KVM_REG_PPC_TB_OFFSET (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9c)
537
538/* POWER8 registers */
539#define KVM_REG_PPC_SPMC1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9d)
540#define KVM_REG_PPC_SPMC2 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9e)
541#define KVM_REG_PPC_IAMR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9f)
542#define KVM_REG_PPC_TFHAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa0)
543#define KVM_REG_PPC_TFIAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa1)
544#define KVM_REG_PPC_TEXASR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa2)
545#define KVM_REG_PPC_FSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa3)
546#define KVM_REG_PPC_PSPB (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xa4)
547#define KVM_REG_PPC_EBBHR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa5)
548#define KVM_REG_PPC_EBBRR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa6)
549#define KVM_REG_PPC_BESCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa7)
550#define KVM_REG_PPC_TAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa8)
551#define KVM_REG_PPC_DPDES (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa9)
552#define KVM_REG_PPC_DAWR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xaa)
553#define KVM_REG_PPC_DAWRX (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xab)
554#define KVM_REG_PPC_CIABR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xac)
555#define KVM_REG_PPC_IC (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xad)
556#define KVM_REG_PPC_VTB (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xae)
557#define KVM_REG_PPC_CSIGR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xaf)
558#define KVM_REG_PPC_TACR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb0)
559#define KVM_REG_PPC_TCSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb1)
560#define KVM_REG_PPC_PID (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb2)
561#define KVM_REG_PPC_ACOP (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb3)
562
563#define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4)
564#define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5)
565#define KVM_REG_PPC_LPCR_64 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb5)
566#define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6)
567
568/* Architecture compatibility level */
569#define KVM_REG_PPC_ARCH_COMPAT (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb7)
570
571#define KVM_REG_PPC_DABRX (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb8)
572#define KVM_REG_PPC_WORT (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb9)
573#define KVM_REG_PPC_SPRG9 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xba)
574#define KVM_REG_PPC_DBSR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbb)
575
576/* Transactional Memory checkpointed state:
577 * This is all GPRs, all VSX regs and a subset of SPRs
578 */
579#define KVM_REG_PPC_TM (KVM_REG_PPC | 0x80000000)
580/* TM GPRs */
581#define KVM_REG_PPC_TM_GPR0 (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0)
582#define KVM_REG_PPC_TM_GPR(n) (KVM_REG_PPC_TM_GPR0 + (n))
583#define KVM_REG_PPC_TM_GPR31 (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x1f)
584/* TM VSX */
585#define KVM_REG_PPC_TM_VSR0 (KVM_REG_PPC_TM | KVM_REG_SIZE_U128 | 0x20)
586#define KVM_REG_PPC_TM_VSR(n) (KVM_REG_PPC_TM_VSR0 + (n))
587#define KVM_REG_PPC_TM_VSR63 (KVM_REG_PPC_TM | KVM_REG_SIZE_U128 | 0x5f)
588/* TM SPRS */
589#define KVM_REG_PPC_TM_CR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x60)
590#define KVM_REG_PPC_TM_LR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x61)
591#define KVM_REG_PPC_TM_CTR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x62)
592#define KVM_REG_PPC_TM_FPSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x63)
593#define KVM_REG_PPC_TM_AMR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x64)
594#define KVM_REG_PPC_TM_PPR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x65)
595#define KVM_REG_PPC_TM_VRSAVE (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x66)
596#define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67)
597#define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68)
598#define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69)
599
600/* PPC64 eXternal Interrupt Controller Specification */
601#define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */
602
603/* Layout of 64-bit source attribute values */
604#define KVM_XICS_DESTINATION_SHIFT 0
605#define KVM_XICS_DESTINATION_MASK 0xffffffffULL
606#define KVM_XICS_PRIORITY_SHIFT 32
607#define KVM_XICS_PRIORITY_MASK 0xff
608#define KVM_XICS_LEVEL_SENSITIVE (1ULL << 40)
609#define KVM_XICS_MASKED (1ULL << 41)
610#define KVM_XICS_PENDING (1ULL << 42)
611
612#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/tools/arch/powerpc/include/uapi/asm/perf_regs.h b/tools/arch/powerpc/include/uapi/asm/perf_regs.h
new file mode 100644
index 000000000000..6a93209748a1
--- /dev/null
+++ b/tools/arch/powerpc/include/uapi/asm/perf_regs.h
@@ -0,0 +1,50 @@
1#ifndef _UAPI_ASM_POWERPC_PERF_REGS_H
2#define _UAPI_ASM_POWERPC_PERF_REGS_H
3
4enum perf_event_powerpc_regs {
5 PERF_REG_POWERPC_R0,
6 PERF_REG_POWERPC_R1,
7 PERF_REG_POWERPC_R2,
8 PERF_REG_POWERPC_R3,
9 PERF_REG_POWERPC_R4,
10 PERF_REG_POWERPC_R5,
11 PERF_REG_POWERPC_R6,
12 PERF_REG_POWERPC_R7,
13 PERF_REG_POWERPC_R8,
14 PERF_REG_POWERPC_R9,
15 PERF_REG_POWERPC_R10,
16 PERF_REG_POWERPC_R11,
17 PERF_REG_POWERPC_R12,
18 PERF_REG_POWERPC_R13,
19 PERF_REG_POWERPC_R14,
20 PERF_REG_POWERPC_R15,
21 PERF_REG_POWERPC_R16,
22 PERF_REG_POWERPC_R17,
23 PERF_REG_POWERPC_R18,
24 PERF_REG_POWERPC_R19,
25 PERF_REG_POWERPC_R20,
26 PERF_REG_POWERPC_R21,
27 PERF_REG_POWERPC_R22,
28 PERF_REG_POWERPC_R23,
29 PERF_REG_POWERPC_R24,
30 PERF_REG_POWERPC_R25,
31 PERF_REG_POWERPC_R26,
32 PERF_REG_POWERPC_R27,
33 PERF_REG_POWERPC_R28,
34 PERF_REG_POWERPC_R29,
35 PERF_REG_POWERPC_R30,
36 PERF_REG_POWERPC_R31,
37 PERF_REG_POWERPC_NIP,
38 PERF_REG_POWERPC_MSR,
39 PERF_REG_POWERPC_ORIG_R3,
40 PERF_REG_POWERPC_CTR,
41 PERF_REG_POWERPC_LINK,
42 PERF_REG_POWERPC_XER,
43 PERF_REG_POWERPC_CCR,
44 PERF_REG_POWERPC_SOFTE,
45 PERF_REG_POWERPC_TRAP,
46 PERF_REG_POWERPC_DAR,
47 PERF_REG_POWERPC_DSISR,
48 PERF_REG_POWERPC_MAX,
49};
50#endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */
diff --git a/tools/arch/s390/include/uapi/asm/bitsperlong.h b/tools/arch/s390/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..e351ea2ad43e
--- /dev/null
+++ b/tools/arch/s390/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,12 @@
1#ifndef __ASM_S390_BITSPERLONG_H
2#define __ASM_S390_BITSPERLONG_H
3
4#ifndef __s390x__
5#define __BITS_PER_LONG 32
6#else
7#define __BITS_PER_LONG 64
8#endif
9
10#include <asm-generic/bitsperlong.h>
11
12#endif /* __ASM_S390_BITSPERLONG_H */
diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h
new file mode 100644
index 000000000000..3b8e99ef9d58
--- /dev/null
+++ b/tools/arch/s390/include/uapi/asm/kvm.h
@@ -0,0 +1,192 @@
1#ifndef __LINUX_KVM_S390_H
2#define __LINUX_KVM_S390_H
3/*
4 * KVM s390 specific structures and definitions
5 *
6 * Copyright IBM Corp. 2008
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License (version 2 only)
10 * as published by the Free Software Foundation.
11 *
12 * Author(s): Carsten Otte <cotte@de.ibm.com>
13 * Christian Borntraeger <borntraeger@de.ibm.com>
14 */
15#include <linux/types.h>
16
17#define __KVM_S390
18#define __KVM_HAVE_GUEST_DEBUG
19
20/* Device control API: s390-specific devices */
21#define KVM_DEV_FLIC_GET_ALL_IRQS 1
22#define KVM_DEV_FLIC_ENQUEUE 2
23#define KVM_DEV_FLIC_CLEAR_IRQS 3
24#define KVM_DEV_FLIC_APF_ENABLE 4
25#define KVM_DEV_FLIC_APF_DISABLE_WAIT 5
26#define KVM_DEV_FLIC_ADAPTER_REGISTER 6
27#define KVM_DEV_FLIC_ADAPTER_MODIFY 7
28#define KVM_DEV_FLIC_CLEAR_IO_IRQ 8
29/*
30 * We can have up to 4*64k pending subchannels + 8 adapter interrupts,
31 * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts.
32 * There are also sclp and machine checks. This gives us
33 * sizeof(kvm_s390_irq)*(4*65536+8+64*64+1+1) = 72 * 266250 = 19170000
34 * Lets round up to 8192 pages.
35 */
36#define KVM_S390_MAX_FLOAT_IRQS 266250
37#define KVM_S390_FLIC_MAX_BUFFER 0x2000000
38
39struct kvm_s390_io_adapter {
40 __u32 id;
41 __u8 isc;
42 __u8 maskable;
43 __u8 swap;
44 __u8 pad;
45};
46
47#define KVM_S390_IO_ADAPTER_MASK 1
48#define KVM_S390_IO_ADAPTER_MAP 2
49#define KVM_S390_IO_ADAPTER_UNMAP 3
50
51struct kvm_s390_io_adapter_req {
52 __u32 id;
53 __u8 type;
54 __u8 mask;
55 __u16 pad0;
56 __u64 addr;
57};
58
59/* kvm attr_group on vm fd */
60#define KVM_S390_VM_MEM_CTRL 0
61#define KVM_S390_VM_TOD 1
62#define KVM_S390_VM_CRYPTO 2
63#define KVM_S390_VM_CPU_MODEL 3
64
65/* kvm attributes for mem_ctrl */
66#define KVM_S390_VM_MEM_ENABLE_CMMA 0
67#define KVM_S390_VM_MEM_CLR_CMMA 1
68#define KVM_S390_VM_MEM_LIMIT_SIZE 2
69
70#define KVM_S390_NO_MEM_LIMIT U64_MAX
71
72/* kvm attributes for KVM_S390_VM_TOD */
73#define KVM_S390_VM_TOD_LOW 0
74#define KVM_S390_VM_TOD_HIGH 1
75
76/* kvm attributes for KVM_S390_VM_CPU_MODEL */
77/* processor related attributes are r/w */
78#define KVM_S390_VM_CPU_PROCESSOR 0
79struct kvm_s390_vm_cpu_processor {
80 __u64 cpuid;
81 __u16 ibc;
82 __u8 pad[6];
83 __u64 fac_list[256];
84};
85
86/* machine related attributes are r/o */
87#define KVM_S390_VM_CPU_MACHINE 1
88struct kvm_s390_vm_cpu_machine {
89 __u64 cpuid;
90 __u32 ibc;
91 __u8 pad[4];
92 __u64 fac_mask[256];
93 __u64 fac_list[256];
94};
95
96/* kvm attributes for crypto */
97#define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0
98#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1
99#define KVM_S390_VM_CRYPTO_DISABLE_AES_KW 2
100#define KVM_S390_VM_CRYPTO_DISABLE_DEA_KW 3
101
102/* for KVM_GET_REGS and KVM_SET_REGS */
103struct kvm_regs {
104 /* general purpose regs for s390 */
105 __u64 gprs[16];
106};
107
108/* for KVM_GET_SREGS and KVM_SET_SREGS */
109struct kvm_sregs {
110 __u32 acrs[16];
111 __u64 crs[16];
112};
113
114/* for KVM_GET_FPU and KVM_SET_FPU */
115struct kvm_fpu {
116 __u32 fpc;
117 __u64 fprs[16];
118};
119
120#define KVM_GUESTDBG_USE_HW_BP 0x00010000
121
122#define KVM_HW_BP 1
123#define KVM_HW_WP_WRITE 2
124#define KVM_SINGLESTEP 4
125
126struct kvm_debug_exit_arch {
127 __u64 addr;
128 __u8 type;
129 __u8 pad[7]; /* Should be set to 0 */
130};
131
132struct kvm_hw_breakpoint {
133 __u64 addr;
134 __u64 phys_addr;
135 __u64 len;
136 __u8 type;
137 __u8 pad[7]; /* Should be set to 0 */
138};
139
140/* for KVM_SET_GUEST_DEBUG */
141struct kvm_guest_debug_arch {
142 __u32 nr_hw_bp;
143 __u32 pad; /* Should be set to 0 */
144 struct kvm_hw_breakpoint __user *hw_bp;
145};
146
147/* for KVM_SYNC_PFAULT and KVM_REG_S390_PFTOKEN */
148#define KVM_S390_PFAULT_TOKEN_INVALID 0xffffffffffffffffULL
149
150#define KVM_SYNC_PREFIX (1UL << 0)
151#define KVM_SYNC_GPRS (1UL << 1)
152#define KVM_SYNC_ACRS (1UL << 2)
153#define KVM_SYNC_CRS (1UL << 3)
154#define KVM_SYNC_ARCH0 (1UL << 4)
155#define KVM_SYNC_PFAULT (1UL << 5)
156#define KVM_SYNC_VRS (1UL << 6)
157#define KVM_SYNC_RICCB (1UL << 7)
158#define KVM_SYNC_FPRS (1UL << 8)
159/* definition of registers in kvm_run */
160struct kvm_sync_regs {
161 __u64 prefix; /* prefix register */
162 __u64 gprs[16]; /* general purpose registers */
163 __u32 acrs[16]; /* access registers */
164 __u64 crs[16]; /* control registers */
165 __u64 todpr; /* tod programmable register [ARCH0] */
166 __u64 cputm; /* cpu timer [ARCH0] */
167 __u64 ckc; /* clock comparator [ARCH0] */
168 __u64 pp; /* program parameter [ARCH0] */
169 __u64 gbea; /* guest breaking-event address [ARCH0] */
170 __u64 pft; /* pfault token [PFAULT] */
171 __u64 pfs; /* pfault select [PFAULT] */
172 __u64 pfc; /* pfault compare [PFAULT] */
173 union {
174 __u64 vrs[32][2]; /* vector registers (KVM_SYNC_VRS) */
175 __u64 fprs[16]; /* fp registers (KVM_SYNC_FPRS) */
176 };
177 __u8 reserved[512]; /* for future vector expansion */
178 __u32 fpc; /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
179 __u8 padding[52]; /* riccb needs to be 64byte aligned */
180 __u8 riccb[64]; /* runtime instrumentation controls block */
181};
182
183#define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1)
184#define KVM_REG_S390_EPOCHDIFF (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x2)
185#define KVM_REG_S390_CPU_TIMER (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x3)
186#define KVM_REG_S390_CLOCK_COMP (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x4)
187#define KVM_REG_S390_PFTOKEN (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x5)
188#define KVM_REG_S390_PFCOMPARE (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x6)
189#define KVM_REG_S390_PFSELECT (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x7)
190#define KVM_REG_S390_PP (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x8)
191#define KVM_REG_S390_GBEA (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x9)
192#endif
diff --git a/tools/arch/s390/include/uapi/asm/kvm_perf.h b/tools/arch/s390/include/uapi/asm/kvm_perf.h
new file mode 100644
index 000000000000..397282727e21
--- /dev/null
+++ b/tools/arch/s390/include/uapi/asm/kvm_perf.h
@@ -0,0 +1,25 @@
1/*
2 * Definitions for perf-kvm on s390
3 *
4 * Copyright 2014 IBM Corp.
5 * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License (version 2 only)
9 * as published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_KVM_PERF_S390_H
13#define __LINUX_KVM_PERF_S390_H
14
15#include <asm/sie.h>
16
17#define DECODE_STR_LEN 40
18
19#define VCPU_ID "id"
20
21#define KVM_ENTRY_TRACE "kvm:kvm_s390_sie_enter"
22#define KVM_EXIT_TRACE "kvm:kvm_s390_sie_exit"
23#define KVM_EXIT_REASON "icptcode"
24
25#endif
diff --git a/tools/arch/s390/include/uapi/asm/sie.h b/tools/arch/s390/include/uapi/asm/sie.h
new file mode 100644
index 000000000000..8fb5d4a6dd25
--- /dev/null
+++ b/tools/arch/s390/include/uapi/asm/sie.h
@@ -0,0 +1,250 @@
1#ifndef _UAPI_ASM_S390_SIE_H
2#define _UAPI_ASM_S390_SIE_H
3
4#define diagnose_codes \
5 { 0x10, "DIAG (0x10) release pages" }, \
6 { 0x44, "DIAG (0x44) time slice end" }, \
7 { 0x9c, "DIAG (0x9c) time slice end directed" }, \
8 { 0x204, "DIAG (0x204) logical-cpu utilization" }, \
9 { 0x258, "DIAG (0x258) page-reference services" }, \
10 { 0x288, "DIAG (0x288) watchdog functions" }, \
11 { 0x308, "DIAG (0x308) ipl functions" }, \
12 { 0x500, "DIAG (0x500) KVM virtio functions" }, \
13 { 0x501, "DIAG (0x501) KVM breakpoint" }
14
15#define sigp_order_codes \
16 { 0x01, "SIGP sense" }, \
17 { 0x02, "SIGP external call" }, \
18 { 0x03, "SIGP emergency signal" }, \
19 { 0x04, "SIGP start" }, \
20 { 0x05, "SIGP stop" }, \
21 { 0x06, "SIGP restart" }, \
22 { 0x09, "SIGP stop and store status" }, \
23 { 0x0b, "SIGP initial cpu reset" }, \
24 { 0x0c, "SIGP cpu reset" }, \
25 { 0x0d, "SIGP set prefix" }, \
26 { 0x0e, "SIGP store status at address" }, \
27 { 0x12, "SIGP set architecture" }, \
28 { 0x13, "SIGP conditional emergency signal" }, \
29 { 0x15, "SIGP sense running" }, \
30 { 0x16, "SIGP set multithreading"}, \
31 { 0x17, "SIGP store additional status ait address"}
32
33#define icpt_prog_codes \
34 { 0x0001, "Prog Operation" }, \
35 { 0x0002, "Prog Privileged Operation" }, \
36 { 0x0003, "Prog Execute" }, \
37 { 0x0004, "Prog Protection" }, \
38 { 0x0005, "Prog Addressing" }, \
39 { 0x0006, "Prog Specification" }, \
40 { 0x0007, "Prog Data" }, \
41 { 0x0008, "Prog Fixedpoint overflow" }, \
42 { 0x0009, "Prog Fixedpoint divide" }, \
43 { 0x000A, "Prog Decimal overflow" }, \
44 { 0x000B, "Prog Decimal divide" }, \
45 { 0x000C, "Prog HFP exponent overflow" }, \
46 { 0x000D, "Prog HFP exponent underflow" }, \
47 { 0x000E, "Prog HFP significance" }, \
48 { 0x000F, "Prog HFP divide" }, \
49 { 0x0010, "Prog Segment translation" }, \
50 { 0x0011, "Prog Page translation" }, \
51 { 0x0012, "Prog Translation specification" }, \
52 { 0x0013, "Prog Special operation" }, \
53 { 0x0015, "Prog Operand" }, \
54 { 0x0016, "Prog Trace table" }, \
55 { 0x0017, "Prog ASNtranslation specification" }, \
56 { 0x001C, "Prog Spaceswitch event" }, \
57 { 0x001D, "Prog HFP square root" }, \
58 { 0x001F, "Prog PCtranslation specification" }, \
59 { 0x0020, "Prog AFX translation" }, \
60 { 0x0021, "Prog ASX translation" }, \
61 { 0x0022, "Prog LX translation" }, \
62 { 0x0023, "Prog EX translation" }, \
63 { 0x0024, "Prog Primary authority" }, \
64 { 0x0025, "Prog Secondary authority" }, \
65 { 0x0026, "Prog LFXtranslation exception" }, \
66 { 0x0027, "Prog LSXtranslation exception" }, \
67 { 0x0028, "Prog ALET specification" }, \
68 { 0x0029, "Prog ALEN translation" }, \
69 { 0x002A, "Prog ALE sequence" }, \
70 { 0x002B, "Prog ASTE validity" }, \
71 { 0x002C, "Prog ASTE sequence" }, \
72 { 0x002D, "Prog Extended authority" }, \
73 { 0x002E, "Prog LSTE sequence" }, \
74 { 0x002F, "Prog ASTE instance" }, \
75 { 0x0030, "Prog Stack full" }, \
76 { 0x0031, "Prog Stack empty" }, \
77 { 0x0032, "Prog Stack specification" }, \
78 { 0x0033, "Prog Stack type" }, \
79 { 0x0034, "Prog Stack operation" }, \
80 { 0x0039, "Prog Region first translation" }, \
81 { 0x003A, "Prog Region second translation" }, \
82 { 0x003B, "Prog Region third translation" }, \
83 { 0x0040, "Prog Monitor event" }, \
84 { 0x0080, "Prog PER event" }, \
85 { 0x0119, "Prog Crypto operation" }
86
87#define exit_code_ipa0(ipa0, opcode, mnemonic) \
88 { (ipa0 << 8 | opcode), #ipa0 " " mnemonic }
89#define exit_code(opcode, mnemonic) \
90 { opcode, mnemonic }
91
92#define icpt_insn_codes \
93 exit_code_ipa0(0x01, 0x01, "PR"), \
94 exit_code_ipa0(0x01, 0x04, "PTFF"), \
95 exit_code_ipa0(0x01, 0x07, "SCKPF"), \
96 exit_code_ipa0(0xAA, 0x00, "RINEXT"), \
97 exit_code_ipa0(0xAA, 0x01, "RION"), \
98 exit_code_ipa0(0xAA, 0x02, "TRIC"), \
99 exit_code_ipa0(0xAA, 0x03, "RIOFF"), \
100 exit_code_ipa0(0xAA, 0x04, "RIEMIT"), \
101 exit_code_ipa0(0xB2, 0x02, "STIDP"), \
102 exit_code_ipa0(0xB2, 0x04, "SCK"), \
103 exit_code_ipa0(0xB2, 0x05, "STCK"), \
104 exit_code_ipa0(0xB2, 0x06, "SCKC"), \
105 exit_code_ipa0(0xB2, 0x07, "STCKC"), \
106 exit_code_ipa0(0xB2, 0x08, "SPT"), \
107 exit_code_ipa0(0xB2, 0x09, "STPT"), \
108 exit_code_ipa0(0xB2, 0x0d, "PTLB"), \
109 exit_code_ipa0(0xB2, 0x10, "SPX"), \
110 exit_code_ipa0(0xB2, 0x11, "STPX"), \
111 exit_code_ipa0(0xB2, 0x12, "STAP"), \
112 exit_code_ipa0(0xB2, 0x14, "SIE"), \
113 exit_code_ipa0(0xB2, 0x16, "SETR"), \
114 exit_code_ipa0(0xB2, 0x17, "STETR"), \
115 exit_code_ipa0(0xB2, 0x18, "PC"), \
116 exit_code_ipa0(0xB2, 0x20, "SERVC"), \
117 exit_code_ipa0(0xB2, 0x21, "IPTE"), \
118 exit_code_ipa0(0xB2, 0x28, "PT"), \
119 exit_code_ipa0(0xB2, 0x29, "ISKE"), \
120 exit_code_ipa0(0xB2, 0x2a, "RRBE"), \
121 exit_code_ipa0(0xB2, 0x2b, "SSKE"), \
122 exit_code_ipa0(0xB2, 0x2c, "TB"), \
123 exit_code_ipa0(0xB2, 0x2e, "PGIN"), \
124 exit_code_ipa0(0xB2, 0x2f, "PGOUT"), \
125 exit_code_ipa0(0xB2, 0x30, "CSCH"), \
126 exit_code_ipa0(0xB2, 0x31, "HSCH"), \
127 exit_code_ipa0(0xB2, 0x32, "MSCH"), \
128 exit_code_ipa0(0xB2, 0x33, "SSCH"), \
129 exit_code_ipa0(0xB2, 0x34, "STSCH"), \
130 exit_code_ipa0(0xB2, 0x35, "TSCH"), \
131 exit_code_ipa0(0xB2, 0x36, "TPI"), \
132 exit_code_ipa0(0xB2, 0x37, "SAL"), \
133 exit_code_ipa0(0xB2, 0x38, "RSCH"), \
134 exit_code_ipa0(0xB2, 0x39, "STCRW"), \
135 exit_code_ipa0(0xB2, 0x3a, "STCPS"), \
136 exit_code_ipa0(0xB2, 0x3b, "RCHP"), \
137 exit_code_ipa0(0xB2, 0x3c, "SCHM"), \
138 exit_code_ipa0(0xB2, 0x40, "BAKR"), \
139 exit_code_ipa0(0xB2, 0x48, "PALB"), \
140 exit_code_ipa0(0xB2, 0x4c, "TAR"), \
141 exit_code_ipa0(0xB2, 0x50, "CSP"), \
142 exit_code_ipa0(0xB2, 0x54, "MVPG"), \
143 exit_code_ipa0(0xB2, 0x58, "BSG"), \
144 exit_code_ipa0(0xB2, 0x5a, "BSA"), \
145 exit_code_ipa0(0xB2, 0x5f, "CHSC"), \
146 exit_code_ipa0(0xB2, 0x74, "SIGA"), \
147 exit_code_ipa0(0xB2, 0x76, "XSCH"), \
148 exit_code_ipa0(0xB2, 0x78, "STCKE"), \
149 exit_code_ipa0(0xB2, 0x7c, "STCKF"), \
150 exit_code_ipa0(0xB2, 0x7d, "STSI"), \
151 exit_code_ipa0(0xB2, 0xb0, "STFLE"), \
152 exit_code_ipa0(0xB2, 0xb1, "STFL"), \
153 exit_code_ipa0(0xB2, 0xb2, "LPSWE"), \
154 exit_code_ipa0(0xB2, 0xf8, "TEND"), \
155 exit_code_ipa0(0xB2, 0xfc, "TABORT"), \
156 exit_code_ipa0(0xB9, 0x1e, "KMAC"), \
157 exit_code_ipa0(0xB9, 0x28, "PCKMO"), \
158 exit_code_ipa0(0xB9, 0x2a, "KMF"), \
159 exit_code_ipa0(0xB9, 0x2b, "KMO"), \
160 exit_code_ipa0(0xB9, 0x2d, "KMCTR"), \
161 exit_code_ipa0(0xB9, 0x2e, "KM"), \
162 exit_code_ipa0(0xB9, 0x2f, "KMC"), \
163 exit_code_ipa0(0xB9, 0x3e, "KIMD"), \
164 exit_code_ipa0(0xB9, 0x3f, "KLMD"), \
165 exit_code_ipa0(0xB9, 0x8a, "CSPG"), \
166 exit_code_ipa0(0xB9, 0x8d, "EPSW"), \
167 exit_code_ipa0(0xB9, 0x8e, "IDTE"), \
168 exit_code_ipa0(0xB9, 0x8f, "CRDTE"), \
169 exit_code_ipa0(0xB9, 0x9c, "EQBS"), \
170 exit_code_ipa0(0xB9, 0xa2, "PTF"), \
171 exit_code_ipa0(0xB9, 0xab, "ESSA"), \
172 exit_code_ipa0(0xB9, 0xae, "RRBM"), \
173 exit_code_ipa0(0xB9, 0xaf, "PFMF"), \
174 exit_code_ipa0(0xE3, 0x03, "LRAG"), \
175 exit_code_ipa0(0xE3, 0x13, "LRAY"), \
176 exit_code_ipa0(0xE3, 0x25, "NTSTG"), \
177 exit_code_ipa0(0xE5, 0x00, "LASP"), \
178 exit_code_ipa0(0xE5, 0x01, "TPROT"), \
179 exit_code_ipa0(0xE5, 0x60, "TBEGIN"), \
180 exit_code_ipa0(0xE5, 0x61, "TBEGINC"), \
181 exit_code_ipa0(0xEB, 0x25, "STCTG"), \
182 exit_code_ipa0(0xEB, 0x2f, "LCTLG"), \
183 exit_code_ipa0(0xEB, 0x60, "LRIC"), \
184 exit_code_ipa0(0xEB, 0x61, "STRIC"), \
185 exit_code_ipa0(0xEB, 0x62, "MRIC"), \
186 exit_code_ipa0(0xEB, 0x8a, "SQBS"), \
187 exit_code_ipa0(0xC8, 0x01, "ECTG"), \
188 exit_code(0x0a, "SVC"), \
189 exit_code(0x80, "SSM"), \
190 exit_code(0x82, "LPSW"), \
191 exit_code(0x83, "DIAG"), \
192 exit_code(0xae, "SIGP"), \
193 exit_code(0xac, "STNSM"), \
194 exit_code(0xad, "STOSM"), \
195 exit_code(0xb1, "LRA"), \
196 exit_code(0xb6, "STCTL"), \
197 exit_code(0xb7, "LCTL"), \
198 exit_code(0xee, "PLO")
199
200#define sie_intercept_code \
201 { 0x00, "Host interruption" }, \
202 { 0x04, "Instruction" }, \
203 { 0x08, "Program interruption" }, \
204 { 0x0c, "Instruction and program interruption" }, \
205 { 0x10, "External request" }, \
206 { 0x14, "External interruption" }, \
207 { 0x18, "I/O request" }, \
208 { 0x1c, "Wait state" }, \
209 { 0x20, "Validity" }, \
210 { 0x28, "Stop request" }, \
211 { 0x2c, "Operation exception" }, \
212 { 0x38, "Partial-execution" }, \
213 { 0x3c, "I/O interruption" }, \
214 { 0x40, "I/O instruction" }, \
215 { 0x48, "Timing subset" }
216
217/*
218 * This is the simple interceptable instructions decoder.
219 *
220 * It will be used as userspace interface and it can be used in places
221 * that does not allow to use general decoder functions,
222 * such as trace events declarations.
223 *
224 * Some userspace tools may want to parse this code
225 * and would be confused by switch(), if() and other statements,
226 * but they can understand conditional operator.
227 */
228#define INSN_DECODE_IPA0(ipa0, insn, rshift, mask) \
229 (insn >> 56) == (ipa0) ? \
230 ((ipa0 << 8) | ((insn >> rshift) & mask)) :
231
232#define INSN_DECODE(insn) (insn >> 56)
233
234/*
235 * The macro icpt_insn_decoder() takes an intercepted instruction
236 * and returns a key, which can be used to find a mnemonic name
237 * of the instruction in the icpt_insn_codes table.
238 */
239#define icpt_insn_decoder(insn) ( \
240 INSN_DECODE_IPA0(0x01, insn, 48, 0xff) \
241 INSN_DECODE_IPA0(0xaa, insn, 48, 0x0f) \
242 INSN_DECODE_IPA0(0xb2, insn, 48, 0xff) \
243 INSN_DECODE_IPA0(0xb9, insn, 48, 0xff) \
244 INSN_DECODE_IPA0(0xe3, insn, 48, 0xff) \
245 INSN_DECODE_IPA0(0xe5, insn, 48, 0xff) \
246 INSN_DECODE_IPA0(0xeb, insn, 16, 0xff) \
247 INSN_DECODE_IPA0(0xc8, insn, 48, 0x0f) \
248 INSN_DECODE(insn))
249
250#endif /* _UAPI_ASM_S390_SIE_H */
diff --git a/tools/arch/score/include/uapi/asm/bitsperlong.h b/tools/arch/score/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..86ff337aa459
--- /dev/null
+++ b/tools/arch/score/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_BITSPERLONG_H
2#define _ASM_SCORE_BITSPERLONG_H
3
4#include <asm-generic/bitsperlong.h>
5
6#endif /* _ASM_SCORE_BITSPERLONG_H */
diff --git a/tools/arch/sparc/include/uapi/asm/bitsperlong.h b/tools/arch/sparc/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..b62dd907d7c3
--- /dev/null
+++ b/tools/arch/sparc/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,12 @@
1#ifndef __ASM_ALPHA_BITSPERLONG_H
2#define __ASM_ALPHA_BITSPERLONG_H
3
4#if defined(__sparc__) && defined(__arch64__)
5#define __BITS_PER_LONG 64
6#else
7#define __BITS_PER_LONG 32
8#endif
9
10#include <asm-generic/bitsperlong.h>
11
12#endif /* __ASM_ALPHA_BITSPERLONG_H */
diff --git a/tools/arch/tile/include/uapi/asm/bitsperlong.h b/tools/arch/tile/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..58c771f2af2f
--- /dev/null
+++ b/tools/arch/tile/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15#ifndef _ASM_TILE_BITSPERLONG_H
16#define _ASM_TILE_BITSPERLONG_H
17
18#ifdef __LP64__
19# define __BITS_PER_LONG 64
20#else
21# define __BITS_PER_LONG 32
22#endif
23
24#include <asm-generic/bitsperlong.h>
25
26#endif /* _ASM_TILE_BITSPERLONG_H */
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
new file mode 100644
index 000000000000..4a413485f9eb
--- /dev/null
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -0,0 +1,316 @@
1#ifndef _ASM_X86_CPUFEATURES_H
2#define _ASM_X86_CPUFEATURES_H
3
4#ifndef _ASM_X86_REQUIRED_FEATURES_H
5#include <asm/required-features.h>
6#endif
7
8#ifndef _ASM_X86_DISABLED_FEATURES_H
9#include <asm/disabled-features.h>
10#endif
11
12/*
13 * Defines x86 CPU feature bits
14 */
15#define NCAPINTS 18 /* N 32-bit words worth of info */
16#define NBUGINTS 1 /* N 32-bit bug flags */
17
18/*
19 * Note: If the comment begins with a quoted string, that string is used
20 * in /proc/cpuinfo instead of the macro name. If the string is "",
21 * this feature bit is not displayed in /proc/cpuinfo at all.
22 */
23
24/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
25#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */
26#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */
27#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */
28#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */
29#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */
30#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */
31#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */
32#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */
33#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */
34#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */
35#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */
36#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */
37#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */
38#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */
39#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */
40 /* (plus FCMOVcc, FCOMI with FPU) */
41#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */
42#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */
43#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */
44#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */
45#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */
46#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */
47#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */
48#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
49#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */
50#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */
51#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */
52#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */
53#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */
54#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */
55#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */
56
57/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
58/* Don't duplicate feature flags which are redundant with Intel! */
59#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */
60#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */
61#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */
62#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */
63#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */
64#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */
65#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */
66#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */
67#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */
68#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */
69
70/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
71#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */
72#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */
73#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */
74
75/* Other features, Linux-defined mapping, word 3 */
76/* This range is used for feature bits which conflict or are synthesized */
77#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */
78#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */
79#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */
80#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */
81/* cpu types for specific tunings: */
82#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */
83#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */
84#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */
85#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */
86#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */
87#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */
88#define X86_FEATURE_ART ( 3*32+10) /* Platform has always running timer (ART) */
89#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */
90#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */
91#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */
92#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */
93#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */
94#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */
95#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */
96#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */
97#define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */
98#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
99#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */
100#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */
101#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */
102#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */
103/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */
104#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */
105#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
106#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
107#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
108#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
109#define X86_FEATURE_MCE_RECOVERY ( 3*32+31) /* cpu has recoverable machine checks */
110
111/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
112#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */
113#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */
114#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */
115#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */
116#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */
117#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */
118#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */
119#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */
120#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */
121#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */
122#define X86_FEATURE_CID ( 4*32+10) /* Context ID */
123#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */
124#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */
125#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */
126#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */
127#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */
128#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */
129#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */
130#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */
131#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */
132#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */
133#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */
134#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */
135#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */
136#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */
137#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
138#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */
139#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */
140#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */
141#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */
142#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */
143
144/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
145#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */
146#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */
147#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
148#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */
149#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */
150#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */
151#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */
152#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */
153#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */
154#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */
155
156/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
157#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */
158#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */
159#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */
160#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */
161#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */
162#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */
163#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */
164#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */
165#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */
166#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */
167#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */
168#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */
169#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */
170#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */
171#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */
172#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */
173#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */
174#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */
175#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */
176#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */
177#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
178#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */
179#define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */
180#define X86_FEATURE_PTSC ( 6*32+27) /* performance time-stamp counter */
181#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */
182#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
183
184/*
185 * Auxiliary flags: Linux defined - For features scattered in various
186 * CPUID levels like 0x6, 0xA etc, word 7.
187 *
188 * Reuse free bits when adding new feature flags!
189 */
190
191#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */
192#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
193
194#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
195#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
196
197#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
198
199/* Virtualization flags: Linux defined, word 8 */
200#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
201#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */
202#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */
203#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */
204#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */
205
206#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */
207#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */
208
209
210/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
211#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
212#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */
213#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */
214#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */
215#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */
216#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */
217#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */
218#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */
219#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */
220#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */
221#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */
222#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */
223#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */
224#define X86_FEATURE_AVX512DQ ( 9*32+17) /* AVX-512 DQ (Double/Quad granular) Instructions */
225#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */
226#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */
227#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */
228#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */
229#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
230#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
231#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
232#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
233#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
234#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */
235#define X86_FEATURE_AVX512BW ( 9*32+30) /* AVX-512 BW (Byte/Word granular) Instructions */
236#define X86_FEATURE_AVX512VL ( 9*32+31) /* AVX-512 VL (128/256 Vector Length) Extensions */
237
238/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */
239#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */
240#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */
241#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */
242#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */
243
244/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */
245#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */
246
247/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
248#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
249#define X86_FEATURE_CQM_MBM_TOTAL (12*32+ 1) /* LLC Total MBM monitoring */
250#define X86_FEATURE_CQM_MBM_LOCAL (12*32+ 2) /* LLC Local MBM monitoring */
251
252/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
253#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
254#define X86_FEATURE_IRPERF (13*32+1) /* Instructions Retired Count */
255
256/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */
257#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
258#define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */
259#define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */
260#define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */
261#define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */
262#define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */
263#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */
264#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */
265#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */
266#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */
267
268/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */
269#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */
270#define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */
271#define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */
272#define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */
273#define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */
274#define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */
275#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */
276#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */
277#define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */
278#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */
279#define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */
280
281/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
282#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
283#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
284
285/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */
286#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */
287#define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
288#define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
289
290/*
291 * BUG word(s)
292 */
293#define X86_BUG(x) (NCAPINTS*32 + (x))
294
295#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */
296#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */
297#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */
298#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */
299#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */
300#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */
301#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
302#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
303#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
304#define X86_BUG_NULL_SEG X86_BUG(9) /* Nulling a selector preserves the base */
305#define X86_BUG_SWAPGS_FENCE X86_BUG(10) /* SWAPGS without input dep on GS */
306
307
308#ifdef CONFIG_X86_32
309/*
310 * 64-bit kernels don't use X86_BUG_ESPFIX. Make the define conditional
311 * to avoid confusion.
312 */
313#define X86_BUG_ESPFIX X86_BUG(9) /* "" IRET to 16-bit SS corrupts ESP/RSP high bits */
314#endif
315
316#endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h
new file mode 100644
index 000000000000..911e9358ceb1
--- /dev/null
+++ b/tools/arch/x86/include/asm/disabled-features.h
@@ -0,0 +1,60 @@
1#ifndef _ASM_X86_DISABLED_FEATURES_H
2#define _ASM_X86_DISABLED_FEATURES_H
3
4/* These features, although they might be available in a CPU
5 * will not be used because the compile options to support
6 * them are not present.
7 *
8 * This code allows them to be checked and disabled at
9 * compile time without an explicit #ifdef. Use
10 * cpu_feature_enabled().
11 */
12
13#ifdef CONFIG_X86_INTEL_MPX
14# define DISABLE_MPX 0
15#else
16# define DISABLE_MPX (1<<(X86_FEATURE_MPX & 31))
17#endif
18
19#ifdef CONFIG_X86_64
20# define DISABLE_VME (1<<(X86_FEATURE_VME & 31))
21# define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31))
22# define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31))
23# define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31))
24#else
25# define DISABLE_VME 0
26# define DISABLE_K6_MTRR 0
27# define DISABLE_CYRIX_ARR 0
28# define DISABLE_CENTAUR_MCR 0
29#endif /* CONFIG_X86_64 */
30
31#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
32# define DISABLE_PKU 0
33# define DISABLE_OSPKE 0
34#else
35# define DISABLE_PKU (1<<(X86_FEATURE_PKU & 31))
36# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE & 31))
37#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
38
39/*
40 * Make sure to add features to the correct mask
41 */
42#define DISABLED_MASK0 (DISABLE_VME)
43#define DISABLED_MASK1 0
44#define DISABLED_MASK2 0
45#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
46#define DISABLED_MASK4 0
47#define DISABLED_MASK5 0
48#define DISABLED_MASK6 0
49#define DISABLED_MASK7 0
50#define DISABLED_MASK8 0
51#define DISABLED_MASK9 (DISABLE_MPX)
52#define DISABLED_MASK10 0
53#define DISABLED_MASK11 0
54#define DISABLED_MASK12 0
55#define DISABLED_MASK13 0
56#define DISABLED_MASK14 0
57#define DISABLED_MASK15 0
58#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)
59
60#endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/tools/arch/x86/include/asm/required-features.h b/tools/arch/x86/include/asm/required-features.h
new file mode 100644
index 000000000000..4916144e3c42
--- /dev/null
+++ b/tools/arch/x86/include/asm/required-features.h
@@ -0,0 +1,103 @@
1#ifndef _ASM_X86_REQUIRED_FEATURES_H
2#define _ASM_X86_REQUIRED_FEATURES_H
3
4/* Define minimum CPUID feature set for kernel These bits are checked
5 really early to actually display a visible error message before the
6 kernel dies. Make sure to assign features to the proper mask!
7
8 Some requirements that are not in CPUID yet are also in the
9 CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too.
10
11 The real information is in arch/x86/Kconfig.cpu, this just converts
12 the CONFIGs into a bitmask */
13
14#ifndef CONFIG_MATH_EMULATION
15# define NEED_FPU (1<<(X86_FEATURE_FPU & 31))
16#else
17# define NEED_FPU 0
18#endif
19
20#if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
21# define NEED_PAE (1<<(X86_FEATURE_PAE & 31))
22#else
23# define NEED_PAE 0
24#endif
25
26#ifdef CONFIG_X86_CMPXCHG64
27# define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31))
28#else
29# define NEED_CX8 0
30#endif
31
32#if defined(CONFIG_X86_CMOV) || defined(CONFIG_X86_64)
33# define NEED_CMOV (1<<(X86_FEATURE_CMOV & 31))
34#else
35# define NEED_CMOV 0
36#endif
37
38#ifdef CONFIG_X86_USE_3DNOW
39# define NEED_3DNOW (1<<(X86_FEATURE_3DNOW & 31))
40#else
41# define NEED_3DNOW 0
42#endif
43
44#if defined(CONFIG_X86_P6_NOP) || defined(CONFIG_X86_64)
45# define NEED_NOPL (1<<(X86_FEATURE_NOPL & 31))
46#else
47# define NEED_NOPL 0
48#endif
49
50#ifdef CONFIG_MATOM
51# define NEED_MOVBE (1<<(X86_FEATURE_MOVBE & 31))
52#else
53# define NEED_MOVBE 0
54#endif
55
56#ifdef CONFIG_X86_64
57#ifdef CONFIG_PARAVIRT
58/* Paravirtualized systems may not have PSE or PGE available */
59#define NEED_PSE 0
60#define NEED_PGE 0
61#else
62#define NEED_PSE (1<<(X86_FEATURE_PSE) & 31)
63#define NEED_PGE (1<<(X86_FEATURE_PGE) & 31)
64#endif
65#define NEED_MSR (1<<(X86_FEATURE_MSR & 31))
66#define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31))
67#define NEED_XMM (1<<(X86_FEATURE_XMM & 31))
68#define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31))
69#define NEED_LM (1<<(X86_FEATURE_LM & 31))
70#else
71#define NEED_PSE 0
72#define NEED_MSR 0
73#define NEED_PGE 0
74#define NEED_FXSR 0
75#define NEED_XMM 0
76#define NEED_XMM2 0
77#define NEED_LM 0
78#endif
79
80#define REQUIRED_MASK0 (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
81 NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
82 NEED_XMM|NEED_XMM2)
83#define SSE_MASK (NEED_XMM|NEED_XMM2)
84
85#define REQUIRED_MASK1 (NEED_LM|NEED_3DNOW)
86
87#define REQUIRED_MASK2 0
88#define REQUIRED_MASK3 (NEED_NOPL)
89#define REQUIRED_MASK4 (NEED_MOVBE)
90#define REQUIRED_MASK5 0
91#define REQUIRED_MASK6 0
92#define REQUIRED_MASK7 0
93#define REQUIRED_MASK8 0
94#define REQUIRED_MASK9 0
95#define REQUIRED_MASK10 0
96#define REQUIRED_MASK11 0
97#define REQUIRED_MASK12 0
98#define REQUIRED_MASK13 0
99#define REQUIRED_MASK14 0
100#define REQUIRED_MASK15 0
101#define REQUIRED_MASK16 0
102
103#endif /* _ASM_X86_REQUIRED_FEATURES_H */
diff --git a/tools/arch/x86/include/asm/unistd_32.h b/tools/arch/x86/include/asm/unistd_32.h
new file mode 100644
index 000000000000..88b3f8c8920c
--- /dev/null
+++ b/tools/arch/x86/include/asm/unistd_32.h
@@ -0,0 +1,12 @@
1#ifndef __NR_perf_event_open
2# define __NR_perf_event_open 336
3#endif
4#ifndef __NR_futex
5# define __NR_futex 240
6#endif
7#ifndef __NR_gettid
8# define __NR_gettid 224
9#endif
10#ifndef __NR_getcpu
11# define __NR_getcpu 318
12#endif
diff --git a/tools/arch/x86/include/asm/unistd_64.h b/tools/arch/x86/include/asm/unistd_64.h
new file mode 100644
index 000000000000..fbdb70ee8837
--- /dev/null
+++ b/tools/arch/x86/include/asm/unistd_64.h
@@ -0,0 +1,12 @@
1#ifndef __NR_perf_event_open
2# define __NR_perf_event_open 298
3#endif
4#ifndef __NR_futex
5# define __NR_futex 202
6#endif
7#ifndef __NR_gettid
8# define __NR_gettid 186
9#endif
10#ifndef __NR_getcpu
11# define __NR_getcpu 309
12#endif
diff --git a/tools/arch/x86/include/uapi/asm/bitsperlong.h b/tools/arch/x86/include/uapi/asm/bitsperlong.h
new file mode 100644
index 000000000000..6e23c543cd80
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/bitsperlong.h
@@ -0,0 +1,12 @@
1#ifndef __ASM_X86_BITSPERLONG_H
2#define __ASM_X86_BITSPERLONG_H
3
4#if defined(__x86_64__) && !defined(__ILP32__)
5# define __BITS_PER_LONG 64
6#else
7# define __BITS_PER_LONG 32
8#endif
9
10#include <asm-generic/bitsperlong.h>
11
12#endif /* __ASM_X86_BITSPERLONG_H */
diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h
new file mode 100644
index 000000000000..739c0c594022
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/kvm.h
@@ -0,0 +1,360 @@
1#ifndef _ASM_X86_KVM_H
2#define _ASM_X86_KVM_H
3
4/*
5 * KVM x86 specific structures and definitions
6 *
7 */
8
9#include <linux/types.h>
10#include <linux/ioctl.h>
11
12#define DE_VECTOR 0
13#define DB_VECTOR 1
14#define BP_VECTOR 3
15#define OF_VECTOR 4
16#define BR_VECTOR 5
17#define UD_VECTOR 6
18#define NM_VECTOR 7
19#define DF_VECTOR 8
20#define TS_VECTOR 10
21#define NP_VECTOR 11
22#define SS_VECTOR 12
23#define GP_VECTOR 13
24#define PF_VECTOR 14
25#define MF_VECTOR 16
26#define AC_VECTOR 17
27#define MC_VECTOR 18
28#define XM_VECTOR 19
29#define VE_VECTOR 20
30
31/* Select x86 specific features in <linux/kvm.h> */
32#define __KVM_HAVE_PIT
33#define __KVM_HAVE_IOAPIC
34#define __KVM_HAVE_IRQ_LINE
35#define __KVM_HAVE_MSI
36#define __KVM_HAVE_USER_NMI
37#define __KVM_HAVE_GUEST_DEBUG
38#define __KVM_HAVE_MSIX
39#define __KVM_HAVE_MCE
40#define __KVM_HAVE_PIT_STATE2
41#define __KVM_HAVE_XEN_HVM
42#define __KVM_HAVE_VCPU_EVENTS
43#define __KVM_HAVE_DEBUGREGS
44#define __KVM_HAVE_XSAVE
45#define __KVM_HAVE_XCRS
46#define __KVM_HAVE_READONLY_MEM
47
48/* Architectural interrupt line count. */
49#define KVM_NR_INTERRUPTS 256
50
51struct kvm_memory_alias {
52 __u32 slot; /* this has a different namespace than memory slots */
53 __u32 flags;
54 __u64 guest_phys_addr;
55 __u64 memory_size;
56 __u64 target_phys_addr;
57};
58
59/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */
60struct kvm_pic_state {
61 __u8 last_irr; /* edge detection */
62 __u8 irr; /* interrupt request register */
63 __u8 imr; /* interrupt mask register */
64 __u8 isr; /* interrupt service register */
65 __u8 priority_add; /* highest irq priority */
66 __u8 irq_base;
67 __u8 read_reg_select;
68 __u8 poll;
69 __u8 special_mask;
70 __u8 init_state;
71 __u8 auto_eoi;
72 __u8 rotate_on_auto_eoi;
73 __u8 special_fully_nested_mode;
74 __u8 init4; /* true if 4 byte init */
75 __u8 elcr; /* PIIX edge/trigger selection */
76 __u8 elcr_mask;
77};
78
79#define KVM_IOAPIC_NUM_PINS 24
80struct kvm_ioapic_state {
81 __u64 base_address;
82 __u32 ioregsel;
83 __u32 id;
84 __u32 irr;
85 __u32 pad;
86 union {
87 __u64 bits;
88 struct {
89 __u8 vector;
90 __u8 delivery_mode:3;
91 __u8 dest_mode:1;
92 __u8 delivery_status:1;
93 __u8 polarity:1;
94 __u8 remote_irr:1;
95 __u8 trig_mode:1;
96 __u8 mask:1;
97 __u8 reserve:7;
98 __u8 reserved[4];
99 __u8 dest_id;
100 } fields;
101 } redirtbl[KVM_IOAPIC_NUM_PINS];
102};
103
104#define KVM_IRQCHIP_PIC_MASTER 0
105#define KVM_IRQCHIP_PIC_SLAVE 1
106#define KVM_IRQCHIP_IOAPIC 2
107#define KVM_NR_IRQCHIPS 3
108
109#define KVM_RUN_X86_SMM (1 << 0)
110
111/* for KVM_GET_REGS and KVM_SET_REGS */
112struct kvm_regs {
113 /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
114 __u64 rax, rbx, rcx, rdx;
115 __u64 rsi, rdi, rsp, rbp;
116 __u64 r8, r9, r10, r11;
117 __u64 r12, r13, r14, r15;
118 __u64 rip, rflags;
119};
120
121/* for KVM_GET_LAPIC and KVM_SET_LAPIC */
122#define KVM_APIC_REG_SIZE 0x400
123struct kvm_lapic_state {
124 char regs[KVM_APIC_REG_SIZE];
125};
126
127struct kvm_segment {
128 __u64 base;
129 __u32 limit;
130 __u16 selector;
131 __u8 type;
132 __u8 present, dpl, db, s, l, g, avl;
133 __u8 unusable;
134 __u8 padding;
135};
136
137struct kvm_dtable {
138 __u64 base;
139 __u16 limit;
140 __u16 padding[3];
141};
142
143
144/* for KVM_GET_SREGS and KVM_SET_SREGS */
145struct kvm_sregs {
146 /* out (KVM_GET_SREGS) / in (KVM_SET_SREGS) */
147 struct kvm_segment cs, ds, es, fs, gs, ss;
148 struct kvm_segment tr, ldt;
149 struct kvm_dtable gdt, idt;
150 __u64 cr0, cr2, cr3, cr4, cr8;
151 __u64 efer;
152 __u64 apic_base;
153 __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
154};
155
156/* for KVM_GET_FPU and KVM_SET_FPU */
157struct kvm_fpu {
158 __u8 fpr[8][16];
159 __u16 fcw;
160 __u16 fsw;
161 __u8 ftwx; /* in fxsave format */
162 __u8 pad1;
163 __u16 last_opcode;
164 __u64 last_ip;
165 __u64 last_dp;
166 __u8 xmm[16][16];
167 __u32 mxcsr;
168 __u32 pad2;
169};
170
171struct kvm_msr_entry {
172 __u32 index;
173 __u32 reserved;
174 __u64 data;
175};
176
177/* for KVM_GET_MSRS and KVM_SET_MSRS */
178struct kvm_msrs {
179 __u32 nmsrs; /* number of msrs in entries */
180 __u32 pad;
181
182 struct kvm_msr_entry entries[0];
183};
184
185/* for KVM_GET_MSR_INDEX_LIST */
186struct kvm_msr_list {
187 __u32 nmsrs; /* number of msrs in entries */
188 __u32 indices[0];
189};
190
191
192struct kvm_cpuid_entry {
193 __u32 function;
194 __u32 eax;
195 __u32 ebx;
196 __u32 ecx;
197 __u32 edx;
198 __u32 padding;
199};
200
201/* for KVM_SET_CPUID */
202struct kvm_cpuid {
203 __u32 nent;
204 __u32 padding;
205 struct kvm_cpuid_entry entries[0];
206};
207
208struct kvm_cpuid_entry2 {
209 __u32 function;
210 __u32 index;
211 __u32 flags;
212 __u32 eax;
213 __u32 ebx;
214 __u32 ecx;
215 __u32 edx;
216 __u32 padding[3];
217};
218
219#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX (1 << 0)
220#define KVM_CPUID_FLAG_STATEFUL_FUNC (1 << 1)
221#define KVM_CPUID_FLAG_STATE_READ_NEXT (1 << 2)
222
223/* for KVM_SET_CPUID2 */
224struct kvm_cpuid2 {
225 __u32 nent;
226 __u32 padding;
227 struct kvm_cpuid_entry2 entries[0];
228};
229
230/* for KVM_GET_PIT and KVM_SET_PIT */
231struct kvm_pit_channel_state {
232 __u32 count; /* can be 65536 */
233 __u16 latched_count;
234 __u8 count_latched;
235 __u8 status_latched;
236 __u8 status;
237 __u8 read_state;
238 __u8 write_state;
239 __u8 write_latch;
240 __u8 rw_mode;
241 __u8 mode;
242 __u8 bcd;
243 __u8 gate;
244 __s64 count_load_time;
245};
246
247struct kvm_debug_exit_arch {
248 __u32 exception;
249 __u32 pad;
250 __u64 pc;
251 __u64 dr6;
252 __u64 dr7;
253};
254
255#define KVM_GUESTDBG_USE_SW_BP 0x00010000
256#define KVM_GUESTDBG_USE_HW_BP 0x00020000
257#define KVM_GUESTDBG_INJECT_DB 0x00040000
258#define KVM_GUESTDBG_INJECT_BP 0x00080000
259
260/* for KVM_SET_GUEST_DEBUG */
261struct kvm_guest_debug_arch {
262 __u64 debugreg[8];
263};
264
265struct kvm_pit_state {
266 struct kvm_pit_channel_state channels[3];
267};
268
269#define KVM_PIT_FLAGS_HPET_LEGACY 0x00000001
270
271struct kvm_pit_state2 {
272 struct kvm_pit_channel_state channels[3];
273 __u32 flags;
274 __u32 reserved[9];
275};
276
277struct kvm_reinject_control {
278 __u8 pit_reinject;
279 __u8 reserved[31];
280};
281
282/* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */
283#define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001
284#define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002
285#define KVM_VCPUEVENT_VALID_SHADOW 0x00000004
286#define KVM_VCPUEVENT_VALID_SMM 0x00000008
287
288/* Interrupt shadow states */
289#define KVM_X86_SHADOW_INT_MOV_SS 0x01
290#define KVM_X86_SHADOW_INT_STI 0x02
291
292/* for KVM_GET/SET_VCPU_EVENTS */
293struct kvm_vcpu_events {
294 struct {
295 __u8 injected;
296 __u8 nr;
297 __u8 has_error_code;
298 __u8 pad;
299 __u32 error_code;
300 } exception;
301 struct {
302 __u8 injected;
303 __u8 nr;
304 __u8 soft;
305 __u8 shadow;
306 } interrupt;
307 struct {
308 __u8 injected;
309 __u8 pending;
310 __u8 masked;
311 __u8 pad;
312 } nmi;
313 __u32 sipi_vector;
314 __u32 flags;
315 struct {
316 __u8 smm;
317 __u8 pending;
318 __u8 smm_inside_nmi;
319 __u8 latched_init;
320 } smi;
321 __u32 reserved[9];
322};
323
324/* for KVM_GET/SET_DEBUGREGS */
325struct kvm_debugregs {
326 __u64 db[4];
327 __u64 dr6;
328 __u64 dr7;
329 __u64 flags;
330 __u64 reserved[9];
331};
332
333/* for KVM_CAP_XSAVE */
334struct kvm_xsave {
335 __u32 region[1024];
336};
337
338#define KVM_MAX_XCRS 16
339
340struct kvm_xcr {
341 __u32 xcr;
342 __u32 reserved;
343 __u64 value;
344};
345
346struct kvm_xcrs {
347 __u32 nr_xcrs;
348 __u32 flags;
349 struct kvm_xcr xcrs[KVM_MAX_XCRS];
350 __u64 padding[16];
351};
352
353/* definition of registers in kvm_run */
354struct kvm_sync_regs {
355};
356
357#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0)
358#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1)
359
360#endif /* _ASM_X86_KVM_H */
diff --git a/tools/arch/x86/include/uapi/asm/kvm_perf.h b/tools/arch/x86/include/uapi/asm/kvm_perf.h
new file mode 100644
index 000000000000..3bb964f88aa1
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/kvm_perf.h
@@ -0,0 +1,16 @@
1#ifndef _ASM_X86_KVM_PERF_H
2#define _ASM_X86_KVM_PERF_H
3
4#include <asm/svm.h>
5#include <asm/vmx.h>
6#include <asm/kvm.h>
7
8#define DECODE_STR_LEN 20
9
10#define VCPU_ID "vcpu_id"
11
12#define KVM_ENTRY_TRACE "kvm:kvm_entry"
13#define KVM_EXIT_TRACE "kvm:kvm_exit"
14#define KVM_EXIT_REASON "exit_reason"
15
16#endif /* _ASM_X86_KVM_PERF_H */
diff --git a/tools/arch/x86/include/uapi/asm/perf_regs.h b/tools/arch/x86/include/uapi/asm/perf_regs.h
new file mode 100644
index 000000000000..3f2207bfd17b
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/perf_regs.h
@@ -0,0 +1,33 @@
1#ifndef _ASM_X86_PERF_REGS_H
2#define _ASM_X86_PERF_REGS_H
3
4enum perf_event_x86_regs {
5 PERF_REG_X86_AX,
6 PERF_REG_X86_BX,
7 PERF_REG_X86_CX,
8 PERF_REG_X86_DX,
9 PERF_REG_X86_SI,
10 PERF_REG_X86_DI,
11 PERF_REG_X86_BP,
12 PERF_REG_X86_SP,
13 PERF_REG_X86_IP,
14 PERF_REG_X86_FLAGS,
15 PERF_REG_X86_CS,
16 PERF_REG_X86_SS,
17 PERF_REG_X86_DS,
18 PERF_REG_X86_ES,
19 PERF_REG_X86_FS,
20 PERF_REG_X86_GS,
21 PERF_REG_X86_R8,
22 PERF_REG_X86_R9,
23 PERF_REG_X86_R10,
24 PERF_REG_X86_R11,
25 PERF_REG_X86_R12,
26 PERF_REG_X86_R13,
27 PERF_REG_X86_R14,
28 PERF_REG_X86_R15,
29
30 PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1,
31 PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1,
32};
33#endif /* _ASM_X86_PERF_REGS_H */
diff --git a/tools/arch/x86/include/uapi/asm/svm.h b/tools/arch/x86/include/uapi/asm/svm.h
new file mode 100644
index 000000000000..3725e145aa58
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/svm.h
@@ -0,0 +1,178 @@
1#ifndef _UAPI__SVM_H
2#define _UAPI__SVM_H
3
4#define SVM_EXIT_READ_CR0 0x000
5#define SVM_EXIT_READ_CR2 0x002
6#define SVM_EXIT_READ_CR3 0x003
7#define SVM_EXIT_READ_CR4 0x004
8#define SVM_EXIT_READ_CR8 0x008
9#define SVM_EXIT_WRITE_CR0 0x010
10#define SVM_EXIT_WRITE_CR2 0x012
11#define SVM_EXIT_WRITE_CR3 0x013
12#define SVM_EXIT_WRITE_CR4 0x014
13#define SVM_EXIT_WRITE_CR8 0x018
14#define SVM_EXIT_READ_DR0 0x020
15#define SVM_EXIT_READ_DR1 0x021
16#define SVM_EXIT_READ_DR2 0x022
17#define SVM_EXIT_READ_DR3 0x023
18#define SVM_EXIT_READ_DR4 0x024
19#define SVM_EXIT_READ_DR5 0x025
20#define SVM_EXIT_READ_DR6 0x026
21#define SVM_EXIT_READ_DR7 0x027
22#define SVM_EXIT_WRITE_DR0 0x030
23#define SVM_EXIT_WRITE_DR1 0x031
24#define SVM_EXIT_WRITE_DR2 0x032
25#define SVM_EXIT_WRITE_DR3 0x033
26#define SVM_EXIT_WRITE_DR4 0x034
27#define SVM_EXIT_WRITE_DR5 0x035
28#define SVM_EXIT_WRITE_DR6 0x036
29#define SVM_EXIT_WRITE_DR7 0x037
30#define SVM_EXIT_EXCP_BASE 0x040
31#define SVM_EXIT_INTR 0x060
32#define SVM_EXIT_NMI 0x061
33#define SVM_EXIT_SMI 0x062
34#define SVM_EXIT_INIT 0x063
35#define SVM_EXIT_VINTR 0x064
36#define SVM_EXIT_CR0_SEL_WRITE 0x065
37#define SVM_EXIT_IDTR_READ 0x066
38#define SVM_EXIT_GDTR_READ 0x067
39#define SVM_EXIT_LDTR_READ 0x068
40#define SVM_EXIT_TR_READ 0x069
41#define SVM_EXIT_IDTR_WRITE 0x06a
42#define SVM_EXIT_GDTR_WRITE 0x06b
43#define SVM_EXIT_LDTR_WRITE 0x06c
44#define SVM_EXIT_TR_WRITE 0x06d
45#define SVM_EXIT_RDTSC 0x06e
46#define SVM_EXIT_RDPMC 0x06f
47#define SVM_EXIT_PUSHF 0x070
48#define SVM_EXIT_POPF 0x071
49#define SVM_EXIT_CPUID 0x072
50#define SVM_EXIT_RSM 0x073
51#define SVM_EXIT_IRET 0x074
52#define SVM_EXIT_SWINT 0x075
53#define SVM_EXIT_INVD 0x076
54#define SVM_EXIT_PAUSE 0x077
55#define SVM_EXIT_HLT 0x078
56#define SVM_EXIT_INVLPG 0x079
57#define SVM_EXIT_INVLPGA 0x07a
58#define SVM_EXIT_IOIO 0x07b
59#define SVM_EXIT_MSR 0x07c
60#define SVM_EXIT_TASK_SWITCH 0x07d
61#define SVM_EXIT_FERR_FREEZE 0x07e
62#define SVM_EXIT_SHUTDOWN 0x07f
63#define SVM_EXIT_VMRUN 0x080
64#define SVM_EXIT_VMMCALL 0x081
65#define SVM_EXIT_VMLOAD 0x082
66#define SVM_EXIT_VMSAVE 0x083
67#define SVM_EXIT_STGI 0x084
68#define SVM_EXIT_CLGI 0x085
69#define SVM_EXIT_SKINIT 0x086
70#define SVM_EXIT_RDTSCP 0x087
71#define SVM_EXIT_ICEBP 0x088
72#define SVM_EXIT_WBINVD 0x089
73#define SVM_EXIT_MONITOR 0x08a
74#define SVM_EXIT_MWAIT 0x08b
75#define SVM_EXIT_MWAIT_COND 0x08c
76#define SVM_EXIT_XSETBV 0x08d
77#define SVM_EXIT_NPF 0x400
78#define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401
79#define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402
80
81#define SVM_EXIT_ERR -1
82
83#define SVM_EXIT_REASONS \
84 { SVM_EXIT_READ_CR0, "read_cr0" }, \
85 { SVM_EXIT_READ_CR2, "read_cr2" }, \
86 { SVM_EXIT_READ_CR3, "read_cr3" }, \
87 { SVM_EXIT_READ_CR4, "read_cr4" }, \
88 { SVM_EXIT_READ_CR8, "read_cr8" }, \
89 { SVM_EXIT_WRITE_CR0, "write_cr0" }, \
90 { SVM_EXIT_WRITE_CR2, "write_cr2" }, \
91 { SVM_EXIT_WRITE_CR3, "write_cr3" }, \
92 { SVM_EXIT_WRITE_CR4, "write_cr4" }, \
93 { SVM_EXIT_WRITE_CR8, "write_cr8" }, \
94 { SVM_EXIT_READ_DR0, "read_dr0" }, \
95 { SVM_EXIT_READ_DR1, "read_dr1" }, \
96 { SVM_EXIT_READ_DR2, "read_dr2" }, \
97 { SVM_EXIT_READ_DR3, "read_dr3" }, \
98 { SVM_EXIT_READ_DR4, "read_dr4" }, \
99 { SVM_EXIT_READ_DR5, "read_dr5" }, \
100 { SVM_EXIT_READ_DR6, "read_dr6" }, \
101 { SVM_EXIT_READ_DR7, "read_dr7" }, \
102 { SVM_EXIT_WRITE_DR0, "write_dr0" }, \
103 { SVM_EXIT_WRITE_DR1, "write_dr1" }, \
104 { SVM_EXIT_WRITE_DR2, "write_dr2" }, \
105 { SVM_EXIT_WRITE_DR3, "write_dr3" }, \
106 { SVM_EXIT_WRITE_DR4, "write_dr4" }, \
107 { SVM_EXIT_WRITE_DR5, "write_dr5" }, \
108 { SVM_EXIT_WRITE_DR6, "write_dr6" }, \
109 { SVM_EXIT_WRITE_DR7, "write_dr7" }, \
110 { SVM_EXIT_EXCP_BASE + DE_VECTOR, "DE excp" }, \
111 { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, \
112 { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, \
113 { SVM_EXIT_EXCP_BASE + OF_VECTOR, "OF excp" }, \
114 { SVM_EXIT_EXCP_BASE + BR_VECTOR, "BR excp" }, \
115 { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, \
116 { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, \
117 { SVM_EXIT_EXCP_BASE + DF_VECTOR, "DF excp" }, \
118 { SVM_EXIT_EXCP_BASE + TS_VECTOR, "TS excp" }, \
119 { SVM_EXIT_EXCP_BASE + NP_VECTOR, "NP excp" }, \
120 { SVM_EXIT_EXCP_BASE + SS_VECTOR, "SS excp" }, \
121 { SVM_EXIT_EXCP_BASE + GP_VECTOR, "GP excp" }, \
122 { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, \
123 { SVM_EXIT_EXCP_BASE + MF_VECTOR, "MF excp" }, \
124 { SVM_EXIT_EXCP_BASE + AC_VECTOR, "AC excp" }, \
125 { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, \
126 { SVM_EXIT_EXCP_BASE + XM_VECTOR, "XF excp" }, \
127 { SVM_EXIT_INTR, "interrupt" }, \
128 { SVM_EXIT_NMI, "nmi" }, \
129 { SVM_EXIT_SMI, "smi" }, \
130 { SVM_EXIT_INIT, "init" }, \
131 { SVM_EXIT_VINTR, "vintr" }, \
132 { SVM_EXIT_CR0_SEL_WRITE, "cr0_sel_write" }, \
133 { SVM_EXIT_IDTR_READ, "read_idtr" }, \
134 { SVM_EXIT_GDTR_READ, "read_gdtr" }, \
135 { SVM_EXIT_LDTR_READ, "read_ldtr" }, \
136 { SVM_EXIT_TR_READ, "read_rt" }, \
137 { SVM_EXIT_IDTR_WRITE, "write_idtr" }, \
138 { SVM_EXIT_GDTR_WRITE, "write_gdtr" }, \
139 { SVM_EXIT_LDTR_WRITE, "write_ldtr" }, \
140 { SVM_EXIT_TR_WRITE, "write_rt" }, \
141 { SVM_EXIT_RDTSC, "rdtsc" }, \
142 { SVM_EXIT_RDPMC, "rdpmc" }, \
143 { SVM_EXIT_PUSHF, "pushf" }, \
144 { SVM_EXIT_POPF, "popf" }, \
145 { SVM_EXIT_CPUID, "cpuid" }, \
146 { SVM_EXIT_RSM, "rsm" }, \
147 { SVM_EXIT_IRET, "iret" }, \
148 { SVM_EXIT_SWINT, "swint" }, \
149 { SVM_EXIT_INVD, "invd" }, \
150 { SVM_EXIT_PAUSE, "pause" }, \
151 { SVM_EXIT_HLT, "hlt" }, \
152 { SVM_EXIT_INVLPG, "invlpg" }, \
153 { SVM_EXIT_INVLPGA, "invlpga" }, \
154 { SVM_EXIT_IOIO, "io" }, \
155 { SVM_EXIT_MSR, "msr" }, \
156 { SVM_EXIT_TASK_SWITCH, "task_switch" }, \
157 { SVM_EXIT_FERR_FREEZE, "ferr_freeze" }, \
158 { SVM_EXIT_SHUTDOWN, "shutdown" }, \
159 { SVM_EXIT_VMRUN, "vmrun" }, \
160 { SVM_EXIT_VMMCALL, "hypercall" }, \
161 { SVM_EXIT_VMLOAD, "vmload" }, \
162 { SVM_EXIT_VMSAVE, "vmsave" }, \
163 { SVM_EXIT_STGI, "stgi" }, \
164 { SVM_EXIT_CLGI, "clgi" }, \
165 { SVM_EXIT_SKINIT, "skinit" }, \
166 { SVM_EXIT_RDTSCP, "rdtscp" }, \
167 { SVM_EXIT_ICEBP, "icebp" }, \
168 { SVM_EXIT_WBINVD, "wbinvd" }, \
169 { SVM_EXIT_MONITOR, "monitor" }, \
170 { SVM_EXIT_MWAIT, "mwait" }, \
171 { SVM_EXIT_XSETBV, "xsetbv" }, \
172 { SVM_EXIT_NPF, "npf" }, \
173 { SVM_EXIT_AVIC_INCOMPLETE_IPI, "avic_incomplete_ipi" }, \
174 { SVM_EXIT_AVIC_UNACCELERATED_ACCESS, "avic_unaccelerated_access" }, \
175 { SVM_EXIT_ERR, "invalid_guest_state" }
176
177
178#endif /* _UAPI__SVM_H */
diff --git a/tools/arch/x86/include/uapi/asm/vmx.h b/tools/arch/x86/include/uapi/asm/vmx.h
new file mode 100644
index 000000000000..5b15d94a33f8
--- /dev/null
+++ b/tools/arch/x86/include/uapi/asm/vmx.h
@@ -0,0 +1,136 @@
1/*
2 * vmx.h: VMX Architecture related definitions
3 * Copyright (c) 2004, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 * A few random additions are:
19 * Copyright (C) 2006 Qumranet
20 * Avi Kivity <avi@qumranet.com>
21 * Yaniv Kamay <yaniv@qumranet.com>
22 *
23 */
24#ifndef _UAPIVMX_H
25#define _UAPIVMX_H
26
27
28#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
29
30#define EXIT_REASON_EXCEPTION_NMI 0
31#define EXIT_REASON_EXTERNAL_INTERRUPT 1
32#define EXIT_REASON_TRIPLE_FAULT 2
33
34#define EXIT_REASON_PENDING_INTERRUPT 7
35#define EXIT_REASON_NMI_WINDOW 8
36#define EXIT_REASON_TASK_SWITCH 9
37#define EXIT_REASON_CPUID 10
38#define EXIT_REASON_HLT 12
39#define EXIT_REASON_INVD 13
40#define EXIT_REASON_INVLPG 14
41#define EXIT_REASON_RDPMC 15
42#define EXIT_REASON_RDTSC 16
43#define EXIT_REASON_VMCALL 18
44#define EXIT_REASON_VMCLEAR 19
45#define EXIT_REASON_VMLAUNCH 20
46#define EXIT_REASON_VMPTRLD 21
47#define EXIT_REASON_VMPTRST 22
48#define EXIT_REASON_VMREAD 23
49#define EXIT_REASON_VMRESUME 24
50#define EXIT_REASON_VMWRITE 25
51#define EXIT_REASON_VMOFF 26
52#define EXIT_REASON_VMON 27
53#define EXIT_REASON_CR_ACCESS 28
54#define EXIT_REASON_DR_ACCESS 29
55#define EXIT_REASON_IO_INSTRUCTION 30
56#define EXIT_REASON_MSR_READ 31
57#define EXIT_REASON_MSR_WRITE 32
58#define EXIT_REASON_INVALID_STATE 33
59#define EXIT_REASON_MSR_LOAD_FAIL 34
60#define EXIT_REASON_MWAIT_INSTRUCTION 36
61#define EXIT_REASON_MONITOR_TRAP_FLAG 37
62#define EXIT_REASON_MONITOR_INSTRUCTION 39
63#define EXIT_REASON_PAUSE_INSTRUCTION 40
64#define EXIT_REASON_MCE_DURING_VMENTRY 41
65#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
66#define EXIT_REASON_APIC_ACCESS 44
67#define EXIT_REASON_EOI_INDUCED 45
68#define EXIT_REASON_EPT_VIOLATION 48
69#define EXIT_REASON_EPT_MISCONFIG 49
70#define EXIT_REASON_INVEPT 50
71#define EXIT_REASON_RDTSCP 51
72#define EXIT_REASON_PREEMPTION_TIMER 52
73#define EXIT_REASON_INVVPID 53
74#define EXIT_REASON_WBINVD 54
75#define EXIT_REASON_XSETBV 55
76#define EXIT_REASON_APIC_WRITE 56
77#define EXIT_REASON_INVPCID 58
78#define EXIT_REASON_PML_FULL 62
79#define EXIT_REASON_XSAVES 63
80#define EXIT_REASON_XRSTORS 64
81#define EXIT_REASON_PCOMMIT 65
82
83#define VMX_EXIT_REASONS \
84 { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \
85 { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, \
86 { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, \
87 { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, \
88 { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, \
89 { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \
90 { EXIT_REASON_CPUID, "CPUID" }, \
91 { EXIT_REASON_HLT, "HLT" }, \
92 { EXIT_REASON_INVLPG, "INVLPG" }, \
93 { EXIT_REASON_RDPMC, "RDPMC" }, \
94 { EXIT_REASON_RDTSC, "RDTSC" }, \
95 { EXIT_REASON_VMCALL, "VMCALL" }, \
96 { EXIT_REASON_VMCLEAR, "VMCLEAR" }, \
97 { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, \
98 { EXIT_REASON_VMPTRLD, "VMPTRLD" }, \
99 { EXIT_REASON_VMPTRST, "VMPTRST" }, \
100 { EXIT_REASON_VMREAD, "VMREAD" }, \
101 { EXIT_REASON_VMRESUME, "VMRESUME" }, \
102 { EXIT_REASON_VMWRITE, "VMWRITE" }, \
103 { EXIT_REASON_VMOFF, "VMOFF" }, \
104 { EXIT_REASON_VMON, "VMON" }, \
105 { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, \
106 { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, \
107 { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, \
108 { EXIT_REASON_MSR_READ, "MSR_READ" }, \
109 { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, \
110 { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, \
111 { EXIT_REASON_MONITOR_TRAP_FLAG, "MONITOR_TRAP_FLAG" }, \
112 { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, \
113 { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, \
114 { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, \
115 { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, \
116 { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \
117 { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \
118 { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \
119 { EXIT_REASON_INVEPT, "INVEPT" }, \
120 { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, \
121 { EXIT_REASON_WBINVD, "WBINVD" }, \
122 { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, \
123 { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \
124 { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \
125 { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, \
126 { EXIT_REASON_INVD, "INVD" }, \
127 { EXIT_REASON_INVVPID, "INVVPID" }, \
128 { EXIT_REASON_INVPCID, "INVPCID" }, \
129 { EXIT_REASON_XSAVES, "XSAVES" }, \
130 { EXIT_REASON_XRSTORS, "XRSTORS" }, \
131 { EXIT_REASON_PCOMMIT, "PCOMMIT" }
132
133#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
134#define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
135
136#endif /* _UAPIVMX_H */
diff --git a/tools/arch/x86/lib/memcpy_64.S b/tools/arch/x86/lib/memcpy_64.S
new file mode 100644
index 000000000000..2ec0b0abbfaa
--- /dev/null
+++ b/tools/arch/x86/lib/memcpy_64.S
@@ -0,0 +1,297 @@
1/* Copyright 2002 Andi Kleen */
2
3#include <linux/linkage.h>
4#include <asm/errno.h>
5#include <asm/cpufeatures.h>
6#include <asm/alternative-asm.h>
7
8/*
9 * We build a jump to memcpy_orig by default which gets NOPped out on
10 * the majority of x86 CPUs which set REP_GOOD. In addition, CPUs which
11 * have the enhanced REP MOVSB/STOSB feature (ERMS), change those NOPs
12 * to a jmp to memcpy_erms which does the REP; MOVSB mem copy.
13 */
14
15.weak memcpy
16
17/*
18 * memcpy - Copy a memory block.
19 *
20 * Input:
21 * rdi destination
22 * rsi source
23 * rdx count
24 *
25 * Output:
26 * rax original destination
27 */
28ENTRY(__memcpy)
29ENTRY(memcpy)
30 ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
31 "jmp memcpy_erms", X86_FEATURE_ERMS
32
33 movq %rdi, %rax
34 movq %rdx, %rcx
35 shrq $3, %rcx
36 andl $7, %edx
37 rep movsq
38 movl %edx, %ecx
39 rep movsb
40 ret
41ENDPROC(memcpy)
42ENDPROC(__memcpy)
43
44/*
45 * memcpy_erms() - enhanced fast string memcpy. This is faster and
46 * simpler than memcpy. Use memcpy_erms when possible.
47 */
48ENTRY(memcpy_erms)
49 movq %rdi, %rax
50 movq %rdx, %rcx
51 rep movsb
52 ret
53ENDPROC(memcpy_erms)
54
55ENTRY(memcpy_orig)
56 movq %rdi, %rax
57
58 cmpq $0x20, %rdx
59 jb .Lhandle_tail
60
61 /*
62 * We check whether memory false dependence could occur,
63 * then jump to corresponding copy mode.
64 */
65 cmp %dil, %sil
66 jl .Lcopy_backward
67 subq $0x20, %rdx
68.Lcopy_forward_loop:
69 subq $0x20, %rdx
70
71 /*
72 * Move in blocks of 4x8 bytes:
73 */
74 movq 0*8(%rsi), %r8
75 movq 1*8(%rsi), %r9
76 movq 2*8(%rsi), %r10
77 movq 3*8(%rsi), %r11
78 leaq 4*8(%rsi), %rsi
79
80 movq %r8, 0*8(%rdi)
81 movq %r9, 1*8(%rdi)
82 movq %r10, 2*8(%rdi)
83 movq %r11, 3*8(%rdi)
84 leaq 4*8(%rdi), %rdi
85 jae .Lcopy_forward_loop
86 addl $0x20, %edx
87 jmp .Lhandle_tail
88
89.Lcopy_backward:
90 /*
91 * Calculate copy position to tail.
92 */
93 addq %rdx, %rsi
94 addq %rdx, %rdi
95 subq $0x20, %rdx
96 /*
97 * At most 3 ALU operations in one cycle,
98 * so append NOPS in the same 16 bytes trunk.
99 */
100 .p2align 4
101.Lcopy_backward_loop:
102 subq $0x20, %rdx
103 movq -1*8(%rsi), %r8
104 movq -2*8(%rsi), %r9
105 movq -3*8(%rsi), %r10
106 movq -4*8(%rsi), %r11
107 leaq -4*8(%rsi), %rsi
108 movq %r8, -1*8(%rdi)
109 movq %r9, -2*8(%rdi)
110 movq %r10, -3*8(%rdi)
111 movq %r11, -4*8(%rdi)
112 leaq -4*8(%rdi), %rdi
113 jae .Lcopy_backward_loop
114
115 /*
116 * Calculate copy position to head.
117 */
118 addl $0x20, %edx
119 subq %rdx, %rsi
120 subq %rdx, %rdi
121.Lhandle_tail:
122 cmpl $16, %edx
123 jb .Lless_16bytes
124
125 /*
126 * Move data from 16 bytes to 31 bytes.
127 */
128 movq 0*8(%rsi), %r8
129 movq 1*8(%rsi), %r9
130 movq -2*8(%rsi, %rdx), %r10
131 movq -1*8(%rsi, %rdx), %r11
132 movq %r8, 0*8(%rdi)
133 movq %r9, 1*8(%rdi)
134 movq %r10, -2*8(%rdi, %rdx)
135 movq %r11, -1*8(%rdi, %rdx)
136 retq
137 .p2align 4
138.Lless_16bytes:
139 cmpl $8, %edx
140 jb .Lless_8bytes
141 /*
142 * Move data from 8 bytes to 15 bytes.
143 */
144 movq 0*8(%rsi), %r8
145 movq -1*8(%rsi, %rdx), %r9
146 movq %r8, 0*8(%rdi)
147 movq %r9, -1*8(%rdi, %rdx)
148 retq
149 .p2align 4
150.Lless_8bytes:
151 cmpl $4, %edx
152 jb .Lless_3bytes
153
154 /*
155 * Move data from 4 bytes to 7 bytes.
156 */
157 movl (%rsi), %ecx
158 movl -4(%rsi, %rdx), %r8d
159 movl %ecx, (%rdi)
160 movl %r8d, -4(%rdi, %rdx)
161 retq
162 .p2align 4
163.Lless_3bytes:
164 subl $1, %edx
165 jb .Lend
166 /*
167 * Move data from 1 bytes to 3 bytes.
168 */
169 movzbl (%rsi), %ecx
170 jz .Lstore_1byte
171 movzbq 1(%rsi), %r8
172 movzbq (%rsi, %rdx), %r9
173 movb %r8b, 1(%rdi)
174 movb %r9b, (%rdi, %rdx)
175.Lstore_1byte:
176 movb %cl, (%rdi)
177
178.Lend:
179 retq
180ENDPROC(memcpy_orig)
181
182#ifndef CONFIG_UML
183/*
184 * memcpy_mcsafe - memory copy with machine check exception handling
185 * Note that we only catch machine checks when reading the source addresses.
186 * Writes to target are posted and don't generate machine checks.
187 */
188ENTRY(memcpy_mcsafe)
189 cmpl $8, %edx
190 /* Less than 8 bytes? Go to byte copy loop */
191 jb .L_no_whole_words
192
193 /* Check for bad alignment of source */
194 testl $7, %esi
195 /* Already aligned */
196 jz .L_8byte_aligned
197
198 /* Copy one byte at a time until source is 8-byte aligned */
199 movl %esi, %ecx
200 andl $7, %ecx
201 subl $8, %ecx
202 negl %ecx
203 subl %ecx, %edx
204.L_copy_leading_bytes:
205 movb (%rsi), %al
206 movb %al, (%rdi)
207 incq %rsi
208 incq %rdi
209 decl %ecx
210 jnz .L_copy_leading_bytes
211
212.L_8byte_aligned:
213 /* Figure out how many whole cache lines (64-bytes) to copy */
214 movl %edx, %ecx
215 andl $63, %edx
216 shrl $6, %ecx
217 jz .L_no_whole_cache_lines
218
219 /* Loop copying whole cache lines */
220.L_cache_w0: movq (%rsi), %r8
221.L_cache_w1: movq 1*8(%rsi), %r9
222.L_cache_w2: movq 2*8(%rsi), %r10
223.L_cache_w3: movq 3*8(%rsi), %r11
224 movq %r8, (%rdi)
225 movq %r9, 1*8(%rdi)
226 movq %r10, 2*8(%rdi)
227 movq %r11, 3*8(%rdi)
228.L_cache_w4: movq 4*8(%rsi), %r8
229.L_cache_w5: movq 5*8(%rsi), %r9
230.L_cache_w6: movq 6*8(%rsi), %r10
231.L_cache_w7: movq 7*8(%rsi), %r11
232 movq %r8, 4*8(%rdi)
233 movq %r9, 5*8(%rdi)
234 movq %r10, 6*8(%rdi)
235 movq %r11, 7*8(%rdi)
236 leaq 64(%rsi), %rsi
237 leaq 64(%rdi), %rdi
238 decl %ecx
239 jnz .L_cache_w0
240
241 /* Are there any trailing 8-byte words? */
242.L_no_whole_cache_lines:
243 movl %edx, %ecx
244 andl $7, %edx
245 shrl $3, %ecx
246 jz .L_no_whole_words
247
248 /* Copy trailing words */
249.L_copy_trailing_words:
250 movq (%rsi), %r8
251 mov %r8, (%rdi)
252 leaq 8(%rsi), %rsi
253 leaq 8(%rdi), %rdi
254 decl %ecx
255 jnz .L_copy_trailing_words
256
257 /* Any trailing bytes? */
258.L_no_whole_words:
259 andl %edx, %edx
260 jz .L_done_memcpy_trap
261
262 /* Copy trailing bytes */
263 movl %edx, %ecx
264.L_copy_trailing_bytes:
265 movb (%rsi), %al
266 movb %al, (%rdi)
267 incq %rsi
268 incq %rdi
269 decl %ecx
270 jnz .L_copy_trailing_bytes
271
272 /* Copy successful. Return zero */
273.L_done_memcpy_trap:
274 xorq %rax, %rax
275 ret
276ENDPROC(memcpy_mcsafe)
277
278 .section .fixup, "ax"
279 /* Return -EFAULT for any failure */
280.L_memcpy_mcsafe_fail:
281 mov $-EFAULT, %rax
282 ret
283
284 .previous
285
286 _ASM_EXTABLE_FAULT(.L_copy_leading_bytes, .L_memcpy_mcsafe_fail)
287 _ASM_EXTABLE_FAULT(.L_cache_w0, .L_memcpy_mcsafe_fail)
288 _ASM_EXTABLE_FAULT(.L_cache_w1, .L_memcpy_mcsafe_fail)
289 _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
290 _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
291 _ASM_EXTABLE_FAULT(.L_cache_w4, .L_memcpy_mcsafe_fail)
292 _ASM_EXTABLE_FAULT(.L_cache_w5, .L_memcpy_mcsafe_fail)
293 _ASM_EXTABLE_FAULT(.L_cache_w6, .L_memcpy_mcsafe_fail)
294 _ASM_EXTABLE_FAULT(.L_cache_w7, .L_memcpy_mcsafe_fail)
295 _ASM_EXTABLE_FAULT(.L_copy_trailing_words, .L_memcpy_mcsafe_fail)
296 _ASM_EXTABLE_FAULT(.L_copy_trailing_bytes, .L_memcpy_mcsafe_fail)
297#endif
diff --git a/tools/arch/x86/lib/memset_64.S b/tools/arch/x86/lib/memset_64.S
new file mode 100644
index 000000000000..e1229ecd2a82
--- /dev/null
+++ b/tools/arch/x86/lib/memset_64.S
@@ -0,0 +1,138 @@
1/* Copyright 2002 Andi Kleen, SuSE Labs */
2
3#include <linux/linkage.h>
4#include <asm/cpufeatures.h>
5#include <asm/alternative-asm.h>
6
7.weak memset
8
9/*
10 * ISO C memset - set a memory block to a byte value. This function uses fast
11 * string to get better performance than the original function. The code is
12 * simpler and shorter than the original function as well.
13 *
14 * rdi destination
15 * rsi value (char)
16 * rdx count (bytes)
17 *
18 * rax original destination
19 */
20ENTRY(memset)
21ENTRY(__memset)
22 /*
23 * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
24 * to use it when possible. If not available, use fast string instructions.
25 *
26 * Otherwise, use original memset function.
27 */
28 ALTERNATIVE_2 "jmp memset_orig", "", X86_FEATURE_REP_GOOD, \
29 "jmp memset_erms", X86_FEATURE_ERMS
30
31 movq %rdi,%r9
32 movq %rdx,%rcx
33 andl $7,%edx
34 shrq $3,%rcx
35 /* expand byte value */
36 movzbl %sil,%esi
37 movabs $0x0101010101010101,%rax
38 imulq %rsi,%rax
39 rep stosq
40 movl %edx,%ecx
41 rep stosb
42 movq %r9,%rax
43 ret
44ENDPROC(memset)
45ENDPROC(__memset)
46
47/*
48 * ISO C memset - set a memory block to a byte value. This function uses
49 * enhanced rep stosb to override the fast string function.
50 * The code is simpler and shorter than the fast string function as well.
51 *
52 * rdi destination
53 * rsi value (char)
54 * rdx count (bytes)
55 *
56 * rax original destination
57 */
58ENTRY(memset_erms)
59 movq %rdi,%r9
60 movb %sil,%al
61 movq %rdx,%rcx
62 rep stosb
63 movq %r9,%rax
64 ret
65ENDPROC(memset_erms)
66
67ENTRY(memset_orig)
68 movq %rdi,%r10
69
70 /* expand byte value */
71 movzbl %sil,%ecx
72 movabs $0x0101010101010101,%rax
73 imulq %rcx,%rax
74
75 /* align dst */
76 movl %edi,%r9d
77 andl $7,%r9d
78 jnz .Lbad_alignment
79.Lafter_bad_alignment:
80
81 movq %rdx,%rcx
82 shrq $6,%rcx
83 jz .Lhandle_tail
84
85 .p2align 4
86.Lloop_64:
87 decq %rcx
88 movq %rax,(%rdi)
89 movq %rax,8(%rdi)
90 movq %rax,16(%rdi)
91 movq %rax,24(%rdi)
92 movq %rax,32(%rdi)
93 movq %rax,40(%rdi)
94 movq %rax,48(%rdi)
95 movq %rax,56(%rdi)
96 leaq 64(%rdi),%rdi
97 jnz .Lloop_64
98
99 /* Handle tail in loops. The loops should be faster than hard
100 to predict jump tables. */
101 .p2align 4
102.Lhandle_tail:
103 movl %edx,%ecx
104 andl $63&(~7),%ecx
105 jz .Lhandle_7
106 shrl $3,%ecx
107 .p2align 4
108.Lloop_8:
109 decl %ecx
110 movq %rax,(%rdi)
111 leaq 8(%rdi),%rdi
112 jnz .Lloop_8
113
114.Lhandle_7:
115 andl $7,%edx
116 jz .Lende
117 .p2align 4
118.Lloop_1:
119 decl %edx
120 movb %al,(%rdi)
121 leaq 1(%rdi),%rdi
122 jnz .Lloop_1
123
124.Lende:
125 movq %r10,%rax
126 ret
127
128.Lbad_alignment:
129 cmpq $7,%rdx
130 jbe .Lhandle_7
131 movq %rax,(%rdi) /* unaligned store */
132 movq $8,%r8
133 subq %r9,%r8
134 addq %r8,%rdi
135 subq %r8,%rdx
136 jmp .Lafter_bad_alignment
137.Lfinal:
138ENDPROC(memset_orig)
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 57c8f98874e8..a120c6b755a9 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -40,6 +40,8 @@ FEATURE_TESTS_BASIC := \
40 libbfd \ 40 libbfd \
41 libelf \ 41 libelf \
42 libelf-getphdrnum \ 42 libelf-getphdrnum \
43 libelf-gelf_getnote \
44 libelf-getshdrstrndx \
43 libelf-mmap \ 45 libelf-mmap \
44 libnuma \ 46 libnuma \
45 numa_num_possible_cpus \ 47 numa_num_possible_cpus \
@@ -60,7 +62,8 @@ FEATURE_TESTS_BASIC := \
60 zlib \ 62 zlib \
61 lzma \ 63 lzma \
62 get_cpuid \ 64 get_cpuid \
63 bpf 65 bpf \
66 sdt
64 67
65# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list 68# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
66# of all feature tests 69# of all feature tests
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 3d88f09e188b..a0b29a311816 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -17,6 +17,8 @@ FILES= \
17 test-cplus-demangle.bin \ 17 test-cplus-demangle.bin \
18 test-libelf.bin \ 18 test-libelf.bin \
19 test-libelf-getphdrnum.bin \ 19 test-libelf-getphdrnum.bin \
20 test-libelf-gelf_getnote.bin \
21 test-libelf-getshdrstrndx.bin \
20 test-libelf-mmap.bin \ 22 test-libelf-mmap.bin \
21 test-libnuma.bin \ 23 test-libnuma.bin \
22 test-numa_num_possible_cpus.bin \ 24 test-numa_num_possible_cpus.bin \
@@ -43,7 +45,8 @@ FILES= \
43 test-zlib.bin \ 45 test-zlib.bin \
44 test-lzma.bin \ 46 test-lzma.bin \
45 test-bpf.bin \ 47 test-bpf.bin \
46 test-get_cpuid.bin 48 test-get_cpuid.bin \
49 test-sdt.bin
47 50
48FILES := $(addprefix $(OUTPUT),$(FILES)) 51FILES := $(addprefix $(OUTPUT),$(FILES))
49 52
@@ -98,6 +101,12 @@ $(OUTPUT)test-libelf-mmap.bin:
98$(OUTPUT)test-libelf-getphdrnum.bin: 101$(OUTPUT)test-libelf-getphdrnum.bin:
99 $(BUILD) -lelf 102 $(BUILD) -lelf
100 103
104$(OUTPUT)test-libelf-gelf_getnote.bin:
105 $(BUILD) -lelf
106
107$(OUTPUT)test-libelf-getshdrstrndx.bin:
108 $(BUILD) -lelf
109
101$(OUTPUT)test-libnuma.bin: 110$(OUTPUT)test-libnuma.bin:
102 $(BUILD) -lnuma 111 $(BUILD) -lnuma
103 112
@@ -205,6 +214,9 @@ $(OUTPUT)test-get_cpuid.bin:
205$(OUTPUT)test-bpf.bin: 214$(OUTPUT)test-bpf.bin:
206 $(BUILD) 215 $(BUILD)
207 216
217$(OUTPUT)test-sdt.bin:
218 $(BUILD)
219
208-include $(OUTPUT)*.d 220-include $(OUTPUT)*.d
209 221
210############################### 222###############################
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index a282e8cb84f3..699e43627397 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -49,6 +49,14 @@
49# include "test-libelf-getphdrnum.c" 49# include "test-libelf-getphdrnum.c"
50#undef main 50#undef main
51 51
52#define main main_test_libelf_gelf_getnote
53# include "test-libelf-gelf_getnote.c"
54#undef main
55
56#define main main_test_libelf_getshdrstrndx
57# include "test-libelf-getshdrstrndx.c"
58#undef main
59
52#define main main_test_libunwind 60#define main main_test_libunwind
53# include "test-libunwind.c" 61# include "test-libunwind.c"
54#undef main 62#undef main
@@ -137,6 +145,10 @@
137# include "test-libcrypto.c" 145# include "test-libcrypto.c"
138#undef main 146#undef main
139 147
148#define main main_test_sdt
149# include "test-sdt.c"
150#undef main
151
140int main(int argc, char *argv[]) 152int main(int argc, char *argv[])
141{ 153{
142 main_test_libpython(); 154 main_test_libpython();
@@ -149,6 +161,8 @@ int main(int argc, char *argv[])
149 main_test_dwarf(); 161 main_test_dwarf();
150 main_test_dwarf_getlocations(); 162 main_test_dwarf_getlocations();
151 main_test_libelf_getphdrnum(); 163 main_test_libelf_getphdrnum();
164 main_test_libelf_gelf_getnote();
165 main_test_libelf_getshdrstrndx();
152 main_test_libunwind(); 166 main_test_libunwind();
153 main_test_libaudit(); 167 main_test_libaudit();
154 main_test_libslang(); 168 main_test_libslang();
@@ -168,6 +182,7 @@ int main(int argc, char *argv[])
168 main_test_get_cpuid(); 182 main_test_get_cpuid();
169 main_test_bpf(); 183 main_test_bpf();
170 main_test_libcrypto(); 184 main_test_libcrypto();
185 main_test_sdt();
171 186
172 return 0; 187 return 0;
173} 188}
diff --git a/tools/build/feature/test-libelf-gelf_getnote.c b/tools/build/feature/test-libelf-gelf_getnote.c
new file mode 100644
index 000000000000..d78cf4d5271f
--- /dev/null
+++ b/tools/build/feature/test-libelf-gelf_getnote.c
@@ -0,0 +1,7 @@
1#include <stdlib.h>
2#include <gelf.h>
3
4int main(void)
5{
6 return gelf_getnote(NULL, 0, NULL, NULL, NULL);
7}
diff --git a/tools/build/feature/test-libelf-getshdrstrndx.c b/tools/build/feature/test-libelf-getshdrstrndx.c
new file mode 100644
index 000000000000..f0c3b47cce28
--- /dev/null
+++ b/tools/build/feature/test-libelf-getshdrstrndx.c
@@ -0,0 +1,8 @@
1#include <libelf.h>
2
3int main(void)
4{
5 size_t dst;
6
7 return elf_getshdrstrndx(0, &dst);
8}
diff --git a/tools/build/feature/test-sdt.c b/tools/build/feature/test-sdt.c
new file mode 100644
index 000000000000..e4531a6e80ea
--- /dev/null
+++ b/tools/build/feature/test-sdt.c
@@ -0,0 +1,7 @@
1#include <sys/sdt.h>
2
3int main(void)
4{
5 DTRACE_PROBE(provider, name);
6 return 0;
7}
diff --git a/tools/gpio/Build b/tools/gpio/Build
new file mode 100644
index 000000000000..620c1937d957
--- /dev/null
+++ b/tools/gpio/Build
@@ -0,0 +1,3 @@
1lsgpio-y += lsgpio.o gpio-utils.o
2gpio-hammer-y += gpio-hammer.o gpio-utils.o
3gpio-event-mon-y += gpio-event-mon.o gpio-utils.o
diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile
index c155d6bc47a7..250a891e6ef0 100644
--- a/tools/gpio/Makefile
+++ b/tools/gpio/Makefile
@@ -1,12 +1,75 @@
1include ../scripts/Makefile.include
2
3bindir ?= /usr/bin
4
5ifeq ($(srctree),)
6srctree := $(patsubst %/,%,$(dir $(shell pwd)))
7srctree := $(patsubst %/,%,$(dir $(srctree)))
8endif
9
10# Do not use make's built-in rules
11# (this improves performance and avoids hard-to-debug behaviour);
12MAKEFLAGS += -r
13
1CC = $(CROSS_COMPILE)gcc 14CC = $(CROSS_COMPILE)gcc
2CFLAGS += -O2 -Wall -g -D_GNU_SOURCE 15LD = $(CROSS_COMPILE)ld
16CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
17
18ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon
19ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
20
21all: $(ALL_PROGRAMS)
3 22
4all: lsgpio 23export srctree OUTPUT CC LD CFLAGS
24include $(srctree)/tools/build/Makefile.include
5 25
6lsgpio: lsgpio.o gpio-utils.o 26#
27# We need the following to be outside of kernel tree
28#
29$(OUTPUT)include/linux/gpio.h: ../../include/uapi/linux/gpio.h
30 mkdir -p $(OUTPUT)include/linux 2>&1 || true
31 ln -sf $(CURDIR)/../../include/uapi/linux/gpio.h $@
7 32
8%.o: %.c gpio-utils.h 33prepare: $(OUTPUT)include/linux/gpio.h
34
35#
36# lsgpio
37#
38LSGPIO_IN := $(OUTPUT)lsgpio-in.o
39$(LSGPIO_IN): prepare FORCE
40 $(Q)$(MAKE) $(build)=lsgpio
41$(OUTPUT)lsgpio: $(LSGPIO_IN)
42 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
43
44#
45# gpio-hammer
46#
47GPIO_HAMMER_IN := $(OUTPUT)gpio-hammer-in.o
48$(GPIO_HAMMER_IN): prepare FORCE
49 $(Q)$(MAKE) $(build)=gpio-hammer
50$(OUTPUT)gpio-hammer: $(GPIO_HAMMER_IN)
51 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
52
53#
54# gpio-event-mon
55#
56GPIO_EVENT_MON_IN := $(OUTPUT)gpio-event-mon-in.o
57$(GPIO_EVENT_MON_IN): prepare FORCE
58 $(Q)$(MAKE) $(build)=gpio-event-mon
59$(OUTPUT)gpio-event-mon: $(GPIO_EVENT_MON_IN)
60 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
9 61
10.PHONY: clean
11clean: 62clean:
12 rm -f *.o lsgpio 63 rm -f $(ALL_PROGRAMS)
64 rm -f $(OUTPUT)include/linux/gpio.h
65 find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
66
67install: $(ALL_PROGRAMS)
68 install -d -m 755 $(DESTDIR)$(bindir); \
69 for program in $(ALL_PROGRAMS); do \
70 install $$program $(DESTDIR)$(bindir); \
71 done
72
73FORCE:
74
75.PHONY: all install clean FORCE prepare
diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
new file mode 100644
index 000000000000..448ed96b3b4f
--- /dev/null
+++ b/tools/gpio/gpio-event-mon.c
@@ -0,0 +1,192 @@
1/*
2 * gpio-hammer - example swiss army knife to shake GPIO lines on a system
3 *
4 * Copyright (C) 2016 Linus Walleij
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * Usage:
11 * gpio-event-mon -n <device-name> -o <offset>
12 */
13
14#include <unistd.h>
15#include <stdlib.h>
16#include <stdbool.h>
17#include <stdio.h>
18#include <dirent.h>
19#include <errno.h>
20#include <string.h>
21#include <poll.h>
22#include <fcntl.h>
23#include <getopt.h>
24#include <inttypes.h>
25#include <sys/ioctl.h>
26#include <linux/gpio.h>
27
28int monitor_device(const char *device_name,
29 unsigned int line,
30 u_int32_t handleflags,
31 u_int32_t eventflags,
32 unsigned int loops)
33{
34 struct gpioevent_request req;
35 struct gpiohandle_data data;
36 char *chrdev_name;
37 int fd;
38 int ret;
39 int i = 0;
40
41 ret = asprintf(&chrdev_name, "/dev/%s", device_name);
42 if (ret < 0)
43 return -ENOMEM;
44
45 fd = open(chrdev_name, 0);
46 if (fd == -1) {
47 ret = -errno;
48 fprintf(stderr, "Failed to open %s\n", chrdev_name);
49 goto exit_close_error;
50 }
51
52 req.lineoffset = line;
53 req.handleflags = handleflags;
54 req.eventflags = eventflags;
55 strcpy(req.consumer_label, "gpio-event-mon");
56
57 ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
58 if (ret == -1) {
59 ret = -errno;
60 fprintf(stderr, "Failed to issue GET EVENT "
61 "IOCTL (%d)\n",
62 ret);
63 goto exit_close_error;
64 }
65
66 /* Read initial states */
67 ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
68 if (ret == -1) {
69 ret = -errno;
70 fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE "
71 "VALUES IOCTL (%d)\n",
72 ret);
73 goto exit_close_error;
74 }
75
76 fprintf(stdout, "Monitoring line %d on %s\n", line, device_name);
77 fprintf(stdout, "Initial line value: %d\n", data.values[0]);
78
79 while (1) {
80 struct gpioevent_data event;
81
82 ret = read(req.fd, &event, sizeof(event));
83 if (ret == -1) {
84 if (errno == -EAGAIN) {
85 fprintf(stderr, "nothing available\n");
86 continue;
87 } else {
88 ret = -errno;
89 fprintf(stderr, "Failed to read event (%d)\n",
90 ret);
91 break;
92 }
93 }
94
95 if (ret != sizeof(event)) {
96 fprintf(stderr, "Reading event failed\n");
97 ret = -EIO;
98 break;
99 }
100 fprintf(stdout, "GPIO EVENT %" PRIu64 ": ", event.timestamp);
101 switch (event.id) {
102 case GPIOEVENT_EVENT_RISING_EDGE:
103 fprintf(stdout, "rising edge");
104 break;
105 case GPIOEVENT_EVENT_FALLING_EDGE:
106 fprintf(stdout, "falling edge");
107 break;
108 default:
109 fprintf(stdout, "unknown event");
110 }
111 fprintf(stdout, "\n");
112
113 i++;
114 if (i == loops)
115 break;
116 }
117
118exit_close_error:
119 if (close(fd) == -1)
120 perror("Failed to close GPIO character device file");
121 free(chrdev_name);
122 return ret;
123}
124
125void print_usage(void)
126{
127 fprintf(stderr, "Usage: gpio-event-mon [options]...\n"
128 "Listen to events on GPIO lines, 0->1 1->0\n"
129 " -n <name> Listen on GPIOs on a named device (must be stated)\n"
130 " -o <n> Offset to monitor\n"
131 " -d Set line as open drain\n"
132 " -s Set line as open source\n"
133 " -r Listen for rising edges\n"
134 " -f Listen for falling edges\n"
135 " [-c <n>] Do <n> loops (optional, infinite loop if not stated)\n"
136 " -? This helptext\n"
137 "\n"
138 "Example:\n"
139 "gpio-event-mon -n gpiochip0 -o 4 -r -f\n"
140 );
141}
142
143int main(int argc, char **argv)
144{
145 const char *device_name = NULL;
146 unsigned int line = -1;
147 unsigned int loops = 0;
148 u_int32_t handleflags = GPIOHANDLE_REQUEST_INPUT;
149 u_int32_t eventflags = 0;
150 int c;
151
152 while ((c = getopt(argc, argv, "c:n:o:dsrf?")) != -1) {
153 switch (c) {
154 case 'c':
155 loops = strtoul(optarg, NULL, 10);
156 break;
157 case 'n':
158 device_name = optarg;
159 break;
160 case 'o':
161 line = strtoul(optarg, NULL, 10);
162 break;
163 case 'd':
164 handleflags |= GPIOHANDLE_REQUEST_OPEN_DRAIN;
165 break;
166 case 's':
167 handleflags |= GPIOHANDLE_REQUEST_OPEN_SOURCE;
168 break;
169 case 'r':
170 eventflags |= GPIOEVENT_REQUEST_RISING_EDGE;
171 break;
172 case 'f':
173 eventflags |= GPIOEVENT_REQUEST_FALLING_EDGE;
174 break;
175 case '?':
176 print_usage();
177 return -1;
178 }
179 }
180
181 if (!device_name || line == -1) {
182 print_usage();
183 return -1;
184 }
185 if (!eventflags) {
186 printf("No flags specified, listening on both rising and "
187 "falling edges\n");
188 eventflags = GPIOEVENT_REQUEST_BOTH_EDGES;
189 }
190 return monitor_device(device_name, line, handleflags,
191 eventflags, loops);
192}
diff --git a/tools/gpio/gpio-hammer.c b/tools/gpio/gpio-hammer.c
new file mode 100644
index 000000000000..37b3f141053d
--- /dev/null
+++ b/tools/gpio/gpio-hammer.c
@@ -0,0 +1,189 @@
1/*
2 * gpio-hammer - example swiss army knife to shake GPIO lines on a system
3 *
4 * Copyright (C) 2016 Linus Walleij
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * Usage:
11 * gpio-hammer -n <device-name> -o <offset1> -o <offset2>
12 */
13
14#include <unistd.h>
15#include <stdlib.h>
16#include <stdbool.h>
17#include <stdio.h>
18#include <dirent.h>
19#include <errno.h>
20#include <string.h>
21#include <poll.h>
22#include <fcntl.h>
23#include <getopt.h>
24#include <sys/ioctl.h>
25#include <linux/gpio.h>
26
27int hammer_device(const char *device_name, unsigned int *lines, int nlines,
28 unsigned int loops)
29{
30 struct gpiohandle_request req;
31 struct gpiohandle_data data;
32 char *chrdev_name;
33 char swirr[] = "-\\|/";
34 int fd;
35 int ret;
36 int i, j;
37 unsigned int iteration = 0;
38
39 ret = asprintf(&chrdev_name, "/dev/%s", device_name);
40 if (ret < 0)
41 return -ENOMEM;
42
43 fd = open(chrdev_name, 0);
44 if (fd == -1) {
45 ret = -errno;
46 fprintf(stderr, "Failed to open %s\n", chrdev_name);
47 goto exit_close_error;
48 }
49
50 /* Request lines as output */
51 for (i = 0; i < nlines; i++)
52 req.lineoffsets[i] = lines[i];
53 req.flags = GPIOHANDLE_REQUEST_OUTPUT; /* Request as output */
54 strcpy(req.consumer_label, "gpio-hammer");
55 req.lines = nlines;
56 ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
57 if (ret == -1) {
58 ret = -errno;
59 fprintf(stderr, "Failed to issue GET LINEHANDLE "
60 "IOCTL (%d)\n",
61 ret);
62 goto exit_close_error;
63 }
64
65 /* Read initial states */
66 ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
67 if (ret == -1) {
68 ret = -errno;
69 fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE "
70 "VALUES IOCTL (%d)\n",
71 ret);
72 goto exit_close_error;
73 }
74 fprintf(stdout, "Hammer lines [");
75 for (i = 0; i < nlines; i++) {
76 fprintf(stdout, "%d", lines[i]);
77 if (i != (nlines - 1))
78 fprintf(stdout, ", ");
79 }
80 fprintf(stdout, "] on %s, initial states: [", device_name);
81 for (i = 0; i < nlines; i++) {
82 fprintf(stdout, "%d", data.values[i]);
83 if (i != (nlines - 1))
84 fprintf(stdout, ", ");
85 }
86 fprintf(stdout, "]\n");
87
88 /* Hammertime! */
89 j = 0;
90 while (1) {
91 /* Invert all lines so we blink */
92 for (i = 0; i < nlines; i++)
93 data.values[i] = !data.values[i];
94
95 ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
96 if (ret == -1) {
97 ret = -errno;
98 fprintf(stderr, "Failed to issue GPIOHANDLE SET LINE "
99 "VALUES IOCTL (%d)\n",
100 ret);
101 goto exit_close_error;
102 }
103 /* Re-read values to get status */
104 ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
105 if (ret == -1) {
106 ret = -errno;
107 fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE "
108 "VALUES IOCTL (%d)\n",
109 ret);
110 goto exit_close_error;
111 }
112
113 fprintf(stdout, "[%c] ", swirr[j]);
114 j++;
115 if (j == sizeof(swirr)-1)
116 j = 0;
117
118 fprintf(stdout, "[");
119 for (i = 0; i < nlines; i++) {
120 fprintf(stdout, "%d: %d", lines[i], data.values[i]);
121 if (i != (nlines - 1))
122 fprintf(stdout, ", ");
123 }
124 fprintf(stdout, "]\r");
125 fflush(stdout);
126 sleep(1);
127 iteration++;
128 if (loops && iteration == loops)
129 break;
130 }
131 fprintf(stdout, "\n");
132 ret = 0;
133
134exit_close_error:
135 if (close(fd) == -1)
136 perror("Failed to close GPIO character device file");
137 free(chrdev_name);
138 return ret;
139}
140
141void print_usage(void)
142{
143 fprintf(stderr, "Usage: gpio-hammer [options]...\n"
144 "Hammer GPIO lines, 0->1->0->1...\n"
145 " -n <name> Hammer GPIOs on a named device (must be stated)\n"
146 " -o <n> Offset[s] to hammer, at least one, several can be stated\n"
147 " [-c <n>] Do <n> loops (optional, infinite loop if not stated)\n"
148 " -? This helptext\n"
149 "\n"
150 "Example:\n"
151 "gpio-hammer -n gpiochip0 -o 4\n"
152 );
153}
154
155int main(int argc, char **argv)
156{
157 const char *device_name = NULL;
158 unsigned int lines[GPIOHANDLES_MAX];
159 unsigned int loops = 0;
160 int nlines;
161 int c;
162 int i;
163
164 i = 0;
165 while ((c = getopt(argc, argv, "c:n:o:?")) != -1) {
166 switch (c) {
167 case 'c':
168 loops = strtoul(optarg, NULL, 10);
169 break;
170 case 'n':
171 device_name = optarg;
172 break;
173 case 'o':
174 lines[i] = strtoul(optarg, NULL, 10);
175 i++;
176 break;
177 case '?':
178 print_usage();
179 return -1;
180 }
181 }
182 nlines = i;
183
184 if (!device_name || !nlines) {
185 print_usage();
186 return -1;
187 }
188 return hammer_device(device_name, lines, nlines, loops);
189}
diff --git a/tools/hv/bondvf.sh b/tools/hv/bondvf.sh
new file mode 100755
index 000000000000..8e960234013d
--- /dev/null
+++ b/tools/hv/bondvf.sh
@@ -0,0 +1,193 @@
1#!/bin/bash
2
3# This example script creates bonding network devices based on synthetic NIC
4# (the virtual network adapter usually provided by Hyper-V) and the matching
5# VF NIC (SRIOV virtual function). So the synthetic NIC and VF NIC can
6# function as one network device, and fail over to the synthetic NIC if VF is
7# down.
8#
9# Usage:
10# - After configured vSwitch and vNIC with SRIOV, start Linux virtual
11# machine (VM)
12# - Run this scripts on the VM. It will create configuration files in
13# distro specific directory.
14# - Reboot the VM, so that the bonding config are enabled.
15#
16# The config files are DHCP by default. You may edit them if you need to change
17# to Static IP or change other settings.
18#
19
20sysdir=/sys/class/net
21netvsc_cls={f8615163-df3e-46c5-913f-f2d2f965ed0e}
22bondcnt=0
23
24# Detect Distro
25if [ -f /etc/redhat-release ];
26then
27 cfgdir=/etc/sysconfig/network-scripts
28 distro=redhat
29elif grep -q 'Ubuntu' /etc/issue
30then
31 cfgdir=/etc/network
32 distro=ubuntu
33elif grep -q 'SUSE' /etc/issue
34then
35 cfgdir=/etc/sysconfig/network
36 distro=suse
37else
38 echo "Unsupported Distro"
39 exit 1
40fi
41
42echo Detected Distro: $distro, or compatible
43
44# Get a list of ethernet names
45list_eth=(`cd $sysdir && ls -d */ | cut -d/ -f1 | grep -v bond`)
46eth_cnt=${#list_eth[@]}
47
48echo List of net devices:
49
50# Get the MAC addresses
51for (( i=0; i < $eth_cnt; i++ ))
52do
53 list_mac[$i]=`cat $sysdir/${list_eth[$i]}/address`
54 echo ${list_eth[$i]}, ${list_mac[$i]}
55done
56
57# Find NIC with matching MAC
58for (( i=0; i < $eth_cnt-1; i++ ))
59do
60 for (( j=i+1; j < $eth_cnt; j++ ))
61 do
62 if [ "${list_mac[$i]}" = "${list_mac[$j]}" ]
63 then
64 list_match[$i]=${list_eth[$j]}
65 break
66 fi
67 done
68done
69
70function create_eth_cfg_redhat {
71 local fn=$cfgdir/ifcfg-$1
72
73 rm -f $fn
74 echo DEVICE=$1 >>$fn
75 echo TYPE=Ethernet >>$fn
76 echo BOOTPROTO=none >>$fn
77 echo ONBOOT=yes >>$fn
78 echo NM_CONTROLLED=no >>$fn
79 echo PEERDNS=yes >>$fn
80 echo IPV6INIT=yes >>$fn
81 echo MASTER=$2 >>$fn
82 echo SLAVE=yes >>$fn
83}
84
85function create_eth_cfg_pri_redhat {
86 create_eth_cfg_redhat $1 $2
87}
88
89function create_bond_cfg_redhat {
90 local fn=$cfgdir/ifcfg-$1
91
92 rm -f $fn
93 echo DEVICE=$1 >>$fn
94 echo TYPE=Bond >>$fn
95 echo BOOTPROTO=dhcp >>$fn
96 echo ONBOOT=yes >>$fn
97 echo NM_CONTROLLED=no >>$fn
98 echo PEERDNS=yes >>$fn
99 echo IPV6INIT=yes >>$fn
100 echo BONDING_MASTER=yes >>$fn
101 echo BONDING_OPTS=\"mode=active-backup miimon=100 primary=$2\" >>$fn
102}
103
104function create_eth_cfg_ubuntu {
105 local fn=$cfgdir/interfaces
106
107 echo $'\n'auto $1 >>$fn
108 echo iface $1 inet manual >>$fn
109 echo bond-master $2 >>$fn
110}
111
112function create_eth_cfg_pri_ubuntu {
113 local fn=$cfgdir/interfaces
114
115 create_eth_cfg_ubuntu $1 $2
116 echo bond-primary $1 >>$fn
117}
118
119function create_bond_cfg_ubuntu {
120 local fn=$cfgdir/interfaces
121
122 echo $'\n'auto $1 >>$fn
123 echo iface $1 inet dhcp >>$fn
124 echo bond-mode active-backup >>$fn
125 echo bond-miimon 100 >>$fn
126 echo bond-slaves none >>$fn
127}
128
129function create_eth_cfg_suse {
130 local fn=$cfgdir/ifcfg-$1
131
132 rm -f $fn
133 echo BOOTPROTO=none >>$fn
134 echo STARTMODE=auto >>$fn
135}
136
137function create_eth_cfg_pri_suse {
138 create_eth_cfg_suse $1
139}
140
141function create_bond_cfg_suse {
142 local fn=$cfgdir/ifcfg-$1
143
144 rm -f $fn
145 echo BOOTPROTO=dhcp >>$fn
146 echo STARTMODE=auto >>$fn
147 echo BONDING_MASTER=yes >>$fn
148 echo BONDING_SLAVE_0=$2 >>$fn
149 echo BONDING_SLAVE_1=$3 >>$fn
150 echo BONDING_MODULE_OPTS=\'mode=active-backup miimon=100 primary=$2\' >>$fn
151}
152
153function create_bond {
154 local bondname=bond$bondcnt
155 local primary
156 local secondary
157
158 local class_id1=`cat $sysdir/$1/device/class_id 2>/dev/null`
159 local class_id2=`cat $sysdir/$2/device/class_id 2>/dev/null`
160
161 if [ "$class_id1" = "$netvsc_cls" ]
162 then
163 primary=$2
164 secondary=$1
165 elif [ "$class_id2" = "$netvsc_cls" ]
166 then
167 primary=$1
168 secondary=$2
169 else
170 return 0
171 fi
172
173 echo $'\nBond name:' $bondname
174
175 echo configuring $primary
176 create_eth_cfg_pri_$distro $primary $bondname
177
178 echo configuring $secondary
179 create_eth_cfg_$distro $secondary $bondname
180
181 echo creating: $bondname with primary slave: $primary
182 create_bond_cfg_$distro $bondname $primary $secondary
183
184 let bondcnt=bondcnt+1
185}
186
187for (( i=0; i < $eth_cnt-1; i++ ))
188do
189 if [ -n "${list_match[$i]}" ]
190 then
191 create_bond ${list_eth[$i]} ${list_match[$i]}
192 fi
193done
diff --git a/tools/iio/Makefile b/tools/iio/Makefile
index 3a7a54f59713..5446d625e17d 100644
--- a/tools/iio/Makefile
+++ b/tools/iio/Makefile
@@ -1,16 +1,31 @@
1CC = $(CROSS_COMPILE)gcc 1CC = $(CROSS_COMPILE)gcc
2CFLAGS += -Wall -g -D_GNU_SOURCE 2CFLAGS += -Wall -g -D_GNU_SOURCE
3 3
4all: iio_event_monitor lsiio generic_buffer 4BINDIR=usr/bin
5INSTALL_PROGRAM=install -m 755 -p
6DEL_FILE=rm -f
7
8all: iio_event_monitor lsiio iio_generic_buffer
5 9
6iio_event_monitor: iio_event_monitor.o iio_utils.o 10iio_event_monitor: iio_event_monitor.o iio_utils.o
7 11
8lsiio: lsiio.o iio_utils.o 12lsiio: lsiio.o iio_utils.o
9 13
10generic_buffer: generic_buffer.o iio_utils.o 14iio_generic_buffer: iio_generic_buffer.o iio_utils.o
11 15
12%.o: %.c iio_utils.h 16%.o: %.c iio_utils.h
13 17
18install:
19 - mkdir -p $(INSTALL_ROOT)/$(BINDIR)
20 - $(INSTALL_PROGRAM) "iio_event_monitor" "$(INSTALL_ROOT)/$(BINDIR)/iio_event_monitor"
21 - $(INSTALL_PROGRAM) "lsiio" "$(INSTALL_ROOT)/$(BINDIR)/lsiio"
22 - $(INSTALL_PROGRAM) "iio_generic_buffer" "$(INSTALL_ROOT)/$(BINDIR)/iio_generic_buffer"
23
24uninstall:
25 $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/iio_event_monitor"
26 $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/lsiio"
27 $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/iio_generic_buffer"
28
14.PHONY: clean 29.PHONY: clean
15clean: 30clean:
16 rm -f *.o iio_event_monitor lsiio generic_buffer 31 rm -f *.o iio_event_monitor lsiio iio_generic_buffer
diff --git a/tools/iio/generic_buffer.c b/tools/iio/iio_generic_buffer.c
index 2429c78de940..0e8a1f7a292d 100644
--- a/tools/iio/generic_buffer.c
+++ b/tools/iio/iio_generic_buffer.c
@@ -32,6 +32,8 @@
32#include <endian.h> 32#include <endian.h>
33#include <getopt.h> 33#include <getopt.h>
34#include <inttypes.h> 34#include <inttypes.h>
35#include <stdbool.h>
36#include <signal.h>
35#include "iio_utils.h" 37#include "iio_utils.h"
36 38
37/** 39/**
@@ -249,11 +251,82 @@ void print_usage(void)
249 " -e Disable wait for event (new data)\n" 251 " -e Disable wait for event (new data)\n"
250 " -g Use trigger-less mode\n" 252 " -g Use trigger-less mode\n"
251 " -l <n> Set buffer length to n samples\n" 253 " -l <n> Set buffer length to n samples\n"
252 " -n <name> Set device name (mandatory)\n" 254 " --device-name -n <name>\n"
253 " -t <name> Set trigger name\n" 255 " --device-num -N <num>\n"
256 " Set device by name or number (mandatory)\n"
257 " --trigger-name -t <name>\n"
258 " --trigger-num -T <num>\n"
259 " Set trigger by name or number\n"
254 " -w <n> Set delay between reads in us (event-less mode)\n"); 260 " -w <n> Set delay between reads in us (event-less mode)\n");
255} 261}
256 262
263enum autochan autochannels = AUTOCHANNELS_DISABLED;
264char *dev_dir_name = NULL;
265char *buf_dir_name = NULL;
266bool current_trigger_set = false;
267
268void cleanup(void)
269{
270 int ret;
271
272 /* Disable trigger */
273 if (dev_dir_name && current_trigger_set) {
274 /* Disconnect the trigger - just write a dummy name. */
275 ret = write_sysfs_string("trigger/current_trigger",
276 dev_dir_name, "NULL");
277 if (ret < 0)
278 fprintf(stderr, "Failed to disable trigger: %s\n",
279 strerror(-ret));
280 current_trigger_set = false;
281 }
282
283 /* Disable buffer */
284 if (buf_dir_name) {
285 ret = write_sysfs_int("enable", buf_dir_name, 0);
286 if (ret < 0)
287 fprintf(stderr, "Failed to disable buffer: %s\n",
288 strerror(-ret));
289 }
290
291 /* Disable channels if auto-enabled */
292 if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) {
293 ret = enable_disable_all_channels(dev_dir_name, 0);
294 if (ret)
295 fprintf(stderr, "Failed to disable all channels\n");
296 autochannels = AUTOCHANNELS_DISABLED;
297 }
298}
299
300void sig_handler(int signum)
301{
302 fprintf(stderr, "Caught signal %d\n", signum);
303 cleanup();
304 exit(-signum);
305}
306
307void register_cleanup(void)
308{
309 struct sigaction sa = { .sa_handler = sig_handler };
310 const int signums[] = { SIGINT, SIGTERM, SIGABRT };
311 int ret, i;
312
313 for (i = 0; i < ARRAY_SIZE(signums); ++i) {
314 ret = sigaction(signums[i], &sa, NULL);
315 if (ret) {
316 perror("Failed to register signal handler");
317 exit(-1);
318 }
319 }
320}
321
322static const struct option longopts[] = {
323 { "device-name", 1, 0, 'n' },
324 { "device-num", 1, 0, 'N' },
325 { "trigger-name", 1, 0, 't' },
326 { "trigger-num", 1, 0, 'T' },
327 { },
328};
329
257int main(int argc, char **argv) 330int main(int argc, char **argv)
258{ 331{
259 unsigned long num_loops = 2; 332 unsigned long num_loops = 2;
@@ -261,26 +334,25 @@ int main(int argc, char **argv)
261 unsigned long buf_len = 128; 334 unsigned long buf_len = 128;
262 335
263 int ret, c, i, j, toread; 336 int ret, c, i, j, toread;
264 int fp; 337 int fp = -1;
265 338
266 int num_channels; 339 int num_channels = 0;
267 char *trigger_name = NULL, *device_name = NULL; 340 char *trigger_name = NULL, *device_name = NULL;
268 char *dev_dir_name, *buf_dir_name;
269 341
270 int datardytrigger = 1; 342 char *data = NULL;
271 char *data;
272 ssize_t read_size; 343 ssize_t read_size;
273 int dev_num, trig_num; 344 int dev_num = -1, trig_num = -1;
274 char *buffer_access; 345 char *buffer_access = NULL;
275 int scan_size; 346 int scan_size;
276 int noevents = 0; 347 int noevents = 0;
277 int notrigger = 0; 348 int notrigger = 0;
278 enum autochan autochannels = AUTOCHANNELS_DISABLED;
279 char *dummy; 349 char *dummy;
280 350
281 struct iio_channel_info *channels; 351 struct iio_channel_info *channels;
282 352
283 while ((c = getopt(argc, argv, "ac:egl:n:t:w:")) != -1) { 353 register_cleanup();
354
355 while ((c = getopt_long(argc, argv, "ac:egl:n:N:t:T:w:", longopts, NULL)) != -1) {
284 switch (c) { 356 switch (c) {
285 case 'a': 357 case 'a':
286 autochannels = AUTOCHANNELS_ENABLED; 358 autochannels = AUTOCHANNELS_ENABLED;
@@ -288,8 +360,10 @@ int main(int argc, char **argv)
288 case 'c': 360 case 'c':
289 errno = 0; 361 errno = 0;
290 num_loops = strtoul(optarg, &dummy, 10); 362 num_loops = strtoul(optarg, &dummy, 10);
291 if (errno) 363 if (errno) {
292 return -errno; 364 ret = -errno;
365 goto error;
366 }
293 367
294 break; 368 break;
295 case 'e': 369 case 'e':
@@ -301,49 +375,102 @@ int main(int argc, char **argv)
301 case 'l': 375 case 'l':
302 errno = 0; 376 errno = 0;
303 buf_len = strtoul(optarg, &dummy, 10); 377 buf_len = strtoul(optarg, &dummy, 10);
304 if (errno) 378 if (errno) {
305 return -errno; 379 ret = -errno;
380 goto error;
381 }
306 382
307 break; 383 break;
308 case 'n': 384 case 'n':
309 device_name = optarg; 385 device_name = strdup(optarg);
386 break;
387 case 'N':
388 errno = 0;
389 dev_num = strtoul(optarg, &dummy, 10);
390 if (errno) {
391 ret = -errno;
392 goto error;
393 }
310 break; 394 break;
311 case 't': 395 case 't':
312 trigger_name = optarg; 396 trigger_name = strdup(optarg);
313 datardytrigger = 0;
314 break; 397 break;
315 case 'w': 398 case 'T':
316 errno = 0; 399 errno = 0;
317 timedelay = strtoul(optarg, &dummy, 10); 400 trig_num = strtoul(optarg, &dummy, 10);
318 if (errno) 401 if (errno)
319 return -errno; 402 return -errno;
320 break; 403 break;
404 case 'w':
405 errno = 0;
406 timedelay = strtoul(optarg, &dummy, 10);
407 if (errno) {
408 ret = -errno;
409 goto error;
410 }
411 break;
321 case '?': 412 case '?':
322 print_usage(); 413 print_usage();
323 return -1; 414 ret = -1;
415 goto error;
324 } 416 }
325 } 417 }
326 418
327 if (!device_name) {
328 fprintf(stderr, "Device name not set\n");
329 print_usage();
330 return -1;
331 }
332
333 /* Find the device requested */ 419 /* Find the device requested */
334 dev_num = find_type_by_name(device_name, "iio:device"); 420 if (dev_num < 0 && !device_name) {
335 if (dev_num < 0) { 421 fprintf(stderr, "Device not set\n");
336 fprintf(stderr, "Failed to find the %s\n", device_name); 422 print_usage();
337 return dev_num; 423 ret = -1;
424 goto error;
425 } else if (dev_num >= 0 && device_name) {
426 fprintf(stderr, "Only one of --device-num or --device-name needs to be set\n");
427 print_usage();
428 ret = -1;
429 goto error;
430 } else if (dev_num < 0) {
431 dev_num = find_type_by_name(device_name, "iio:device");
432 if (dev_num < 0) {
433 fprintf(stderr, "Failed to find the %s\n", device_name);
434 ret = dev_num;
435 goto error;
436 }
338 } 437 }
339
340 printf("iio device number being used is %d\n", dev_num); 438 printf("iio device number being used is %d\n", dev_num);
341 439
342 ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num); 440 ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
343 if (ret < 0) 441 if (ret < 0)
344 return -ENOMEM; 442 return -ENOMEM;
443 /* Fetch device_name if specified by number */
444 if (!device_name) {
445 device_name = malloc(IIO_MAX_NAME_LENGTH);
446 if (!device_name) {
447 ret = -ENOMEM;
448 goto error;
449 }
450 ret = read_sysfs_string("name", dev_dir_name, device_name);
451 if (ret < 0) {
452 fprintf(stderr, "Failed to read name of device %d\n", dev_num);
453 goto error;
454 }
455 }
345 456
346 if (!notrigger) { 457 if (notrigger) {
458 printf("trigger-less mode selected\n");
459 } if (trig_num >= 0) {
460 char *trig_dev_name;
461 ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num);
462 if (ret < 0) {
463 return -ENOMEM;
464 }
465 trigger_name = malloc(IIO_MAX_NAME_LENGTH);
466 ret = read_sysfs_string("name", trig_dev_name, trigger_name);
467 free(trig_dev_name);
468 if (ret < 0) {
469 fprintf(stderr, "Failed to read trigger%d name from\n", trig_num);
470 return ret;
471 }
472 printf("iio trigger number being used is %d\n", trig_num);
473 } else {
347 if (!trigger_name) { 474 if (!trigger_name) {
348 /* 475 /*
349 * Build the trigger name. If it is device associated 476 * Build the trigger name. If it is device associated
@@ -354,7 +481,7 @@ int main(int argc, char **argv)
354 "%s-dev%d", device_name, dev_num); 481 "%s-dev%d", device_name, dev_num);
355 if (ret < 0) { 482 if (ret < 0) {
356 ret = -ENOMEM; 483 ret = -ENOMEM;
357 goto error_free_dev_dir_name; 484 goto error;
358 } 485 }
359 } 486 }
360 487
@@ -367,7 +494,7 @@ int main(int argc, char **argv)
367 "%s-trigger", device_name); 494 "%s-trigger", device_name);
368 if (ret < 0) { 495 if (ret < 0) {
369 ret = -ENOMEM; 496 ret = -ENOMEM;
370 goto error_free_dev_dir_name; 497 goto error;
371 } 498 }
372 } 499 }
373 500
@@ -376,12 +503,10 @@ int main(int argc, char **argv)
376 fprintf(stderr, "Failed to find the trigger %s\n", 503 fprintf(stderr, "Failed to find the trigger %s\n",
377 trigger_name); 504 trigger_name);
378 ret = trig_num; 505 ret = trig_num;
379 goto error_free_triggername; 506 goto error;
380 } 507 }
381 508
382 printf("iio trigger number being used is %d\n", trig_num); 509 printf("iio trigger number being used is %d\n", trig_num);
383 } else {
384 printf("trigger-less mode selected\n");
385 } 510 }
386 511
387 /* 512 /*
@@ -392,7 +517,7 @@ int main(int argc, char **argv)
392 if (ret) { 517 if (ret) {
393 fprintf(stderr, "Problem reading scan element information\n" 518 fprintf(stderr, "Problem reading scan element information\n"
394 "diag %s\n", dev_dir_name); 519 "diag %s\n", dev_dir_name);
395 goto error_free_triggername; 520 goto error;
396 } 521 }
397 if (num_channels && autochannels == AUTOCHANNELS_ENABLED) { 522 if (num_channels && autochannels == AUTOCHANNELS_ENABLED) {
398 fprintf(stderr, "Auto-channels selected but some channels " 523 fprintf(stderr, "Auto-channels selected but some channels "
@@ -407,7 +532,7 @@ int main(int argc, char **argv)
407 ret = enable_disable_all_channels(dev_dir_name, 1); 532 ret = enable_disable_all_channels(dev_dir_name, 1);
408 if (ret) { 533 if (ret) {
409 fprintf(stderr, "Failed to enable all channels\n"); 534 fprintf(stderr, "Failed to enable all channels\n");
410 goto error_free_triggername; 535 goto error;
411 } 536 }
412 537
413 /* This flags that we need to disable the channels again */ 538 /* This flags that we need to disable the channels again */
@@ -419,12 +544,12 @@ int main(int argc, char **argv)
419 fprintf(stderr, "Problem reading scan element " 544 fprintf(stderr, "Problem reading scan element "
420 "information\n" 545 "information\n"
421 "diag %s\n", dev_dir_name); 546 "diag %s\n", dev_dir_name);
422 goto error_disable_channels; 547 goto error;
423 } 548 }
424 if (!num_channels) { 549 if (!num_channels) {
425 fprintf(stderr, "Still no channels after " 550 fprintf(stderr, "Still no channels after "
426 "auto-enabling, giving up\n"); 551 "auto-enabling, giving up\n");
427 goto error_disable_channels; 552 goto error;
428 } 553 }
429 } 554 }
430 555
@@ -436,7 +561,7 @@ int main(int argc, char **argv)
436 "/*_en or pass -a to autoenable channels and " 561 "/*_en or pass -a to autoenable channels and "
437 "try again.\n", dev_dir_name); 562 "try again.\n", dev_dir_name);
438 ret = -ENOENT; 563 ret = -ENOENT;
439 goto error_free_triggername; 564 goto error;
440 } 565 }
441 566
442 /* 567 /*
@@ -448,7 +573,7 @@ int main(int argc, char **argv)
448 "%siio:device%d/buffer", iio_dir, dev_num); 573 "%siio:device%d/buffer", iio_dir, dev_num);
449 if (ret < 0) { 574 if (ret < 0) {
450 ret = -ENOMEM; 575 ret = -ENOMEM;
451 goto error_free_channels; 576 goto error;
452 } 577 }
453 578
454 if (!notrigger) { 579 if (!notrigger) {
@@ -463,34 +588,34 @@ int main(int argc, char **argv)
463 if (ret < 0) { 588 if (ret < 0) {
464 fprintf(stderr, 589 fprintf(stderr,
465 "Failed to write current_trigger file\n"); 590 "Failed to write current_trigger file\n");
466 goto error_free_buf_dir_name; 591 goto error;
467 } 592 }
468 } 593 }
469 594
470 /* Setup ring buffer parameters */ 595 /* Setup ring buffer parameters */
471 ret = write_sysfs_int("length", buf_dir_name, buf_len); 596 ret = write_sysfs_int("length", buf_dir_name, buf_len);
472 if (ret < 0) 597 if (ret < 0)
473 goto error_free_buf_dir_name; 598 goto error;
474 599
475 /* Enable the buffer */ 600 /* Enable the buffer */
476 ret = write_sysfs_int("enable", buf_dir_name, 1); 601 ret = write_sysfs_int("enable", buf_dir_name, 1);
477 if (ret < 0) { 602 if (ret < 0) {
478 fprintf(stderr, 603 fprintf(stderr,
479 "Failed to enable buffer: %s\n", strerror(-ret)); 604 "Failed to enable buffer: %s\n", strerror(-ret));
480 goto error_free_buf_dir_name; 605 goto error;
481 } 606 }
482 607
483 scan_size = size_from_channelarray(channels, num_channels); 608 scan_size = size_from_channelarray(channels, num_channels);
484 data = malloc(scan_size * buf_len); 609 data = malloc(scan_size * buf_len);
485 if (!data) { 610 if (!data) {
486 ret = -ENOMEM; 611 ret = -ENOMEM;
487 goto error_free_buf_dir_name; 612 goto error;
488 } 613 }
489 614
490 ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num); 615 ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
491 if (ret < 0) { 616 if (ret < 0) {
492 ret = -ENOMEM; 617 ret = -ENOMEM;
493 goto error_free_data; 618 goto error;
494 } 619 }
495 620
496 /* Attempt to open non blocking the access dev */ 621 /* Attempt to open non blocking the access dev */
@@ -498,7 +623,7 @@ int main(int argc, char **argv)
498 if (fp == -1) { /* TODO: If it isn't there make the node */ 623 if (fp == -1) { /* TODO: If it isn't there make the node */
499 ret = -errno; 624 ret = -errno;
500 fprintf(stderr, "Failed to open %s\n", buffer_access); 625 fprintf(stderr, "Failed to open %s\n", buffer_access);
501 goto error_free_buffer_access; 626 goto error;
502 } 627 }
503 628
504 for (j = 0; j < num_loops; j++) { 629 for (j = 0; j < num_loops; j++) {
@@ -511,7 +636,7 @@ int main(int argc, char **argv)
511 ret = poll(&pfd, 1, -1); 636 ret = poll(&pfd, 1, -1);
512 if (ret < 0) { 637 if (ret < 0) {
513 ret = -errno; 638 ret = -errno;
514 goto error_close_buffer_access; 639 goto error;
515 } else if (ret == 0) { 640 } else if (ret == 0) {
516 continue; 641 continue;
517 } 642 }
@@ -536,45 +661,21 @@ int main(int argc, char **argv)
536 num_channels); 661 num_channels);
537 } 662 }
538 663
539 /* Stop the buffer */ 664error:
540 ret = write_sysfs_int("enable", buf_dir_name, 0); 665 cleanup();
541 if (ret < 0)
542 goto error_close_buffer_access;
543 666
544 if (!notrigger) 667 if (fp >= 0 && close(fp) == -1)
545 /* Disconnect the trigger - just write a dummy name. */
546 ret = write_sysfs_string("trigger/current_trigger",
547 dev_dir_name, "NULL");
548 if (ret < 0)
549 fprintf(stderr, "Failed to write to %s\n",
550 dev_dir_name);
551
552error_close_buffer_access:
553 if (close(fp) == -1)
554 perror("Failed to close buffer"); 668 perror("Failed to close buffer");
555
556error_free_buffer_access:
557 free(buffer_access); 669 free(buffer_access);
558error_free_data:
559 free(data); 670 free(data);
560error_free_buf_dir_name:
561 free(buf_dir_name); 671 free(buf_dir_name);
562error_free_channels:
563 for (i = num_channels - 1; i >= 0; i--) { 672 for (i = num_channels - 1; i >= 0; i--) {
564 free(channels[i].name); 673 free(channels[i].name);
565 free(channels[i].generic_name); 674 free(channels[i].generic_name);
566 } 675 }
567 free(channels); 676 free(channels);
568error_free_triggername: 677 free(trigger_name);
569 if (datardytrigger) 678 free(device_name);
570 free(trigger_name);
571error_disable_channels:
572 if (autochannels == AUTOCHANNELS_ACTIVE) {
573 ret = enable_disable_all_channels(dev_dir_name, 0);
574 if (ret)
575 fprintf(stderr, "Failed to disable all channels\n");
576 }
577error_free_dev_dir_name:
578 free(dev_dir_name); 679 free(dev_dir_name);
579 680
580 return ret; 681 return ret;
diff --git a/tools/include/asm-generic/bitops/__ffs.h b/tools/include/asm-generic/bitops/__ffs.h
index c94175015a82..b3accfdf24b9 100644
--- a/tools/include/asm-generic/bitops/__ffs.h
+++ b/tools/include/asm-generic/bitops/__ffs.h
@@ -2,6 +2,7 @@
2#define _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ 2#define _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_
3 3
4#include <asm/types.h> 4#include <asm/types.h>
5#include <asm/bitsperlong.h>
5 6
6/** 7/**
7 * __ffs - find first bit in word. 8 * __ffs - find first bit in word.
diff --git a/tools/include/asm-generic/bitops/__fls.h b/tools/include/asm-generic/bitops/__fls.h
index 494c9c615d1c..a60a7ccb6782 100644
--- a/tools/include/asm-generic/bitops/__fls.h
+++ b/tools/include/asm-generic/bitops/__fls.h
@@ -1 +1,43 @@
1#include "../../../../include/asm-generic/bitops/__fls.h" 1#ifndef _ASM_GENERIC_BITOPS___FLS_H_
2#define _ASM_GENERIC_BITOPS___FLS_H_
3
4#include <asm/types.h>
5
6/**
7 * __fls - find last (most-significant) set bit in a long word
8 * @word: the word to search
9 *
10 * Undefined if no set bit exists, so code should check against 0 first.
11 */
12static __always_inline unsigned long __fls(unsigned long word)
13{
14 int num = BITS_PER_LONG - 1;
15
16#if BITS_PER_LONG == 64
17 if (!(word & (~0ul << 32))) {
18 num -= 32;
19 word <<= 32;
20 }
21#endif
22 if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
23 num -= 16;
24 word <<= 16;
25 }
26 if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
27 num -= 8;
28 word <<= 8;
29 }
30 if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
31 num -= 4;
32 word <<= 4;
33 }
34 if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
35 num -= 2;
36 word <<= 2;
37 }
38 if (!(word & (~0ul << (BITS_PER_LONG-1))))
39 num -= 1;
40 return num;
41}
42
43#endif /* _ASM_GENERIC_BITOPS___FLS_H_ */
diff --git a/tools/include/asm-generic/bitops/arch_hweight.h b/tools/include/asm-generic/bitops/arch_hweight.h
index 318bb2b202b0..6a211f40665c 100644
--- a/tools/include/asm-generic/bitops/arch_hweight.h
+++ b/tools/include/asm-generic/bitops/arch_hweight.h
@@ -1 +1,25 @@
1#include "../../../../include/asm-generic/bitops/arch_hweight.h" 1#ifndef _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_
2#define _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_
3
4#include <asm/types.h>
5
6static inline unsigned int __arch_hweight32(unsigned int w)
7{
8 return __sw_hweight32(w);
9}
10
11static inline unsigned int __arch_hweight16(unsigned int w)
12{
13 return __sw_hweight16(w);
14}
15
16static inline unsigned int __arch_hweight8(unsigned int w)
17{
18 return __sw_hweight8(w);
19}
20
21static inline unsigned long __arch_hweight64(__u64 w)
22{
23 return __sw_hweight64(w);
24}
25#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
diff --git a/tools/include/asm-generic/bitops/atomic.h b/tools/include/asm-generic/bitops/atomic.h
index 4bccd7c3d5d6..18663f59d72f 100644
--- a/tools/include/asm-generic/bitops/atomic.h
+++ b/tools/include/asm-generic/bitops/atomic.h
@@ -2,6 +2,7 @@
2#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ 2#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_
3 3
4#include <asm/types.h> 4#include <asm/types.h>
5#include <asm/bitsperlong.h>
5 6
6static inline void set_bit(int nr, unsigned long *addr) 7static inline void set_bit(int nr, unsigned long *addr)
7{ 8{
diff --git a/tools/include/asm-generic/bitops/const_hweight.h b/tools/include/asm-generic/bitops/const_hweight.h
index 0afd644aff83..0a7e06623470 100644
--- a/tools/include/asm-generic/bitops/const_hweight.h
+++ b/tools/include/asm-generic/bitops/const_hweight.h
@@ -1 +1,43 @@
1#include "../../../../include/asm-generic/bitops/const_hweight.h" 1#ifndef _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_
2#define _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_
3
4/*
5 * Compile time versions of __arch_hweightN()
6 */
7#define __const_hweight8(w) \
8 ((unsigned int) \
9 ((!!((w) & (1ULL << 0))) + \
10 (!!((w) & (1ULL << 1))) + \
11 (!!((w) & (1ULL << 2))) + \
12 (!!((w) & (1ULL << 3))) + \
13 (!!((w) & (1ULL << 4))) + \
14 (!!((w) & (1ULL << 5))) + \
15 (!!((w) & (1ULL << 6))) + \
16 (!!((w) & (1ULL << 7)))))
17
18#define __const_hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8 ))
19#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
20#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))
21
22/*
23 * Generic interface.
24 */
25#define hweight8(w) (__builtin_constant_p(w) ? __const_hweight8(w) : __arch_hweight8(w))
26#define hweight16(w) (__builtin_constant_p(w) ? __const_hweight16(w) : __arch_hweight16(w))
27#define hweight32(w) (__builtin_constant_p(w) ? __const_hweight32(w) : __arch_hweight32(w))
28#define hweight64(w) (__builtin_constant_p(w) ? __const_hweight64(w) : __arch_hweight64(w))
29
30/*
31 * Interface for known constant arguments
32 */
33#define HWEIGHT8(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight8(w))
34#define HWEIGHT16(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight16(w))
35#define HWEIGHT32(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight32(w))
36#define HWEIGHT64(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight64(w))
37
38/*
39 * Type invariant interface to the compile time constant hweight functions.
40 */
41#define HWEIGHT(w) HWEIGHT64((u64)w)
42
43#endif /* _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_ */
diff --git a/tools/include/asm-generic/bitops/fls.h b/tools/include/asm-generic/bitops/fls.h
index 0e4995fa0248..0576d1f42f43 100644
--- a/tools/include/asm-generic/bitops/fls.h
+++ b/tools/include/asm-generic/bitops/fls.h
@@ -1 +1,41 @@
1#include "../../../../include/asm-generic/bitops/fls.h" 1#ifndef _ASM_GENERIC_BITOPS_FLS_H_
2#define _ASM_GENERIC_BITOPS_FLS_H_
3
4/**
5 * fls - find last (most-significant) bit set
6 * @x: the word to search
7 *
8 * This is defined the same way as ffs.
9 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
10 */
11
12static __always_inline int fls(int x)
13{
14 int r = 32;
15
16 if (!x)
17 return 0;
18 if (!(x & 0xffff0000u)) {
19 x <<= 16;
20 r -= 16;
21 }
22 if (!(x & 0xff000000u)) {
23 x <<= 8;
24 r -= 8;
25 }
26 if (!(x & 0xf0000000u)) {
27 x <<= 4;
28 r -= 4;
29 }
30 if (!(x & 0xc0000000u)) {
31 x <<= 2;
32 r -= 2;
33 }
34 if (!(x & 0x80000000u)) {
35 x <<= 1;
36 r -= 1;
37 }
38 return r;
39}
40
41#endif /* _ASM_GENERIC_BITOPS_FLS_H_ */
diff --git a/tools/include/asm-generic/bitops/fls64.h b/tools/include/asm-generic/bitops/fls64.h
index 35bee0071e78..b097cf8444e3 100644
--- a/tools/include/asm-generic/bitops/fls64.h
+++ b/tools/include/asm-generic/bitops/fls64.h
@@ -1 +1,36 @@
1#include "../../../../include/asm-generic/bitops/fls64.h" 1#ifndef _ASM_GENERIC_BITOPS_FLS64_H_
2#define _ASM_GENERIC_BITOPS_FLS64_H_
3
4#include <asm/types.h>
5
6/**
7 * fls64 - find last set bit in a 64-bit word
8 * @x: the word to search
9 *
10 * This is defined in a similar way as the libc and compiler builtin
11 * ffsll, but returns the position of the most significant set bit.
12 *
13 * fls64(value) returns 0 if value is 0 or the position of the last
14 * set bit if value is nonzero. The last (most significant) bit is
15 * at position 64.
16 */
17#if BITS_PER_LONG == 32
18static __always_inline int fls64(__u64 x)
19{
20 __u32 h = x >> 32;
21 if (h)
22 return fls(h) + 32;
23 return fls(x);
24}
25#elif BITS_PER_LONG == 64
26static __always_inline int fls64(__u64 x)
27{
28 if (x == 0)
29 return 0;
30 return __fls(x) + 1;
31}
32#else
33#error BITS_PER_LONG not 32 or 64
34#endif
35
36#endif /* _ASM_GENERIC_BITOPS_FLS64_H_ */
diff --git a/tools/include/asm-generic/bitsperlong.h b/tools/include/asm-generic/bitsperlong.h
new file mode 100644
index 000000000000..45eca517efb3
--- /dev/null
+++ b/tools/include/asm-generic/bitsperlong.h
@@ -0,0 +1,20 @@
1#ifndef __ASM_GENERIC_BITS_PER_LONG
2#define __ASM_GENERIC_BITS_PER_LONG
3
4#include <uapi/asm-generic/bitsperlong.h>
5
6#ifdef __SIZEOF_LONG__
7#define BITS_PER_LONG (__CHAR_BIT__ * __SIZEOF_LONG__)
8#else
9#define BITS_PER_LONG __WORDSIZE
10#endif
11
12#if BITS_PER_LONG != __BITS_PER_LONG
13#error Inconsistent word size. Check asm/bitsperlong.h
14#endif
15
16#ifndef BITS_PER_LONG_LONG
17#define BITS_PER_LONG_LONG 64
18#endif
19
20#endif /* __ASM_GENERIC_BITS_PER_LONG */
diff --git a/tools/perf/util/include/asm/alternative-asm.h b/tools/include/asm/alternative-asm.h
index 3a3a0f16456a..2a4d1bfa2988 100644
--- a/tools/perf/util/include/asm/alternative-asm.h
+++ b/tools/include/asm/alternative-asm.h
@@ -1,5 +1,5 @@
1#ifndef _PERF_ASM_ALTERNATIVE_ASM_H 1#ifndef _TOOLS_ASM_ALTERNATIVE_ASM_H
2#define _PERF_ASM_ALTERNATIVE_ASM_H 2#define _TOOLS_ASM_ALTERNATIVE_ASM_H
3 3
4/* Just disable it so we can build arch/x86/lib/memcpy_64.S for perf bench: */ 4/* Just disable it so we can build arch/x86/lib/memcpy_64.S for perf bench: */
5 5
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h
index 5ad9ee1dd7f6..49c929a104ee 100644
--- a/tools/include/linux/bitops.h
+++ b/tools/include/linux/bitops.h
@@ -9,7 +9,9 @@
9#define __WORDSIZE (__SIZEOF_LONG__ * 8) 9#define __WORDSIZE (__SIZEOF_LONG__ * 8)
10#endif 10#endif
11 11
12#define BITS_PER_LONG __WORDSIZE 12#ifndef BITS_PER_LONG
13# define BITS_PER_LONG __WORDSIZE
14#endif
13 15
14#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) 16#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
15#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) 17#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
index fa7208a32d76..e33fc1df3935 100644
--- a/tools/include/linux/compiler.h
+++ b/tools/include/linux/compiler.h
@@ -9,6 +9,17 @@
9# define __always_inline inline __attribute__((always_inline)) 9# define __always_inline inline __attribute__((always_inline))
10#endif 10#endif
11 11
12#ifdef __ANDROID__
13/*
14 * FIXME: Big hammer to get rid of tons of:
15 * "warning: always_inline function might not be inlinable"
16 *
17 * At least on android-ndk-r12/platforms/android-24/arch-arm
18 */
19#undef __always_inline
20#define __always_inline inline
21#endif
22
12#define __user 23#define __user
13 24
14#ifndef __attribute_const__ 25#ifndef __attribute_const__
diff --git a/tools/include/linux/hash.h b/tools/include/linux/hash.h
index d026c6573018..ad6fa21d977b 100644
--- a/tools/include/linux/hash.h
+++ b/tools/include/linux/hash.h
@@ -1,5 +1,104 @@
1#include "../../../include/linux/hash.h" 1#ifndef _LINUX_HASH_H
2#define _LINUX_HASH_H
3/* Fast hashing routine for ints, longs and pointers.
4 (C) 2002 Nadia Yvette Chambers, IBM */
2 5
3#ifndef _TOOLS_LINUX_HASH_H 6#include <asm/types.h>
4#define _TOOLS_LINUX_HASH_H 7#include <linux/compiler.h>
8
9/*
10 * The "GOLDEN_RATIO_PRIME" is used in ifs/btrfs/brtfs_inode.h and
11 * fs/inode.c. It's not actually prime any more (the previous primes
12 * were actively bad for hashing), but the name remains.
13 */
14#if BITS_PER_LONG == 32
15#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32
16#define hash_long(val, bits) hash_32(val, bits)
17#elif BITS_PER_LONG == 64
18#define hash_long(val, bits) hash_64(val, bits)
19#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64
20#else
21#error Wordsize not 32 or 64
22#endif
23
24/*
25 * This hash multiplies the input by a large odd number and takes the
26 * high bits. Since multiplication propagates changes to the most
27 * significant end only, it is essential that the high bits of the
28 * product be used for the hash value.
29 *
30 * Chuck Lever verified the effectiveness of this technique:
31 * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
32 *
33 * Although a random odd number will do, it turns out that the golden
34 * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice
35 * properties. (See Knuth vol 3, section 6.4, exercise 9.)
36 *
37 * These are the negative, (1 - phi) = phi**2 = (3 - sqrt(5))/2,
38 * which is very slightly easier to multiply by and makes no
39 * difference to the hash distribution.
40 */
41#define GOLDEN_RATIO_32 0x61C88647
42#define GOLDEN_RATIO_64 0x61C8864680B583EBull
43
44#ifdef CONFIG_HAVE_ARCH_HASH
45/* This header may use the GOLDEN_RATIO_xx constants */
46#include <asm/hash.h>
47#endif
48
49/*
50 * The _generic versions exist only so lib/test_hash.c can compare
51 * the arch-optimized versions with the generic.
52 *
53 * Note that if you change these, any <asm/hash.h> that aren't updated
54 * to match need to have their HAVE_ARCH_* define values updated so the
55 * self-test will not false-positive.
56 */
57#ifndef HAVE_ARCH__HASH_32
58#define __hash_32 __hash_32_generic
59#endif
60static inline u32 __hash_32_generic(u32 val)
61{
62 return val * GOLDEN_RATIO_32;
63}
64
65#ifndef HAVE_ARCH_HASH_32
66#define hash_32 hash_32_generic
5#endif 67#endif
68static inline u32 hash_32_generic(u32 val, unsigned int bits)
69{
70 /* High bits are more random, so use them. */
71 return __hash_32(val) >> (32 - bits);
72}
73
74#ifndef HAVE_ARCH_HASH_64
75#define hash_64 hash_64_generic
76#endif
77static __always_inline u32 hash_64_generic(u64 val, unsigned int bits)
78{
79#if BITS_PER_LONG == 64
80 /* 64x64-bit multiply is efficient on all 64-bit processors */
81 return val * GOLDEN_RATIO_64 >> (64 - bits);
82#else
83 /* Hash 64 bits using only 32x32-bit multiply. */
84 return hash_32((u32)val ^ __hash_32(val >> 32), bits);
85#endif
86}
87
88static inline u32 hash_ptr(const void *ptr, unsigned int bits)
89{
90 return hash_long((unsigned long)ptr, bits);
91}
92
93/* This really should be called fold32_ptr; it does no hashing to speak of. */
94static inline u32 hash32_ptr(const void *ptr)
95{
96 unsigned long val = (unsigned long)ptr;
97
98#if BITS_PER_LONG == 64
99 val ^= (val >> 32);
100#endif
101 return (u32)val;
102}
103
104#endif /* _LINUX_HASH_H */
diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h
index 76df53539c2a..28607db02bd3 100644
--- a/tools/include/linux/kernel.h
+++ b/tools/include/linux/kernel.h
@@ -2,8 +2,7 @@
2#define __TOOLS_LINUX_KERNEL_H 2#define __TOOLS_LINUX_KERNEL_H
3 3
4#include <stdarg.h> 4#include <stdarg.h>
5#include <stdio.h> 5#include <stddef.h>
6#include <stdlib.h>
7#include <assert.h> 6#include <assert.h>
8 7
9#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 8#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
@@ -70,29 +69,8 @@
70#define cpu_to_le64(x) (x) 69#define cpu_to_le64(x) (x)
71#define cpu_to_le32(x) (x) 70#define cpu_to_le32(x) (x)
72 71
73static inline int 72int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
74vscnprintf(char *buf, size_t size, const char *fmt, va_list args) 73int scnprintf(char * buf, size_t size, const char * fmt, ...);
75{
76 int i;
77 ssize_t ssize = size;
78
79 i = vsnprintf(buf, size, fmt, args);
80
81 return (i >= ssize) ? (ssize - 1) : i;
82}
83
84static inline int scnprintf(char * buf, size_t size, const char * fmt, ...)
85{
86 va_list args;
87 ssize_t ssize = size;
88 int i;
89
90 va_start(args, fmt);
91 i = vsnprintf(buf, size, fmt, args);
92 va_end(args);
93
94 return (i >= ssize) ? (ssize - 1) : i;
95}
96 74
97/* 75/*
98 * This looks more complex than it should be. But we need to 76 * This looks more complex than it should be. But we need to
diff --git a/tools/include/linux/poison.h b/tools/include/linux/poison.h
index 0c27bdf14233..51334edec506 100644
--- a/tools/include/linux/poison.h
+++ b/tools/include/linux/poison.h
@@ -1 +1,90 @@
1#include "../../../include/linux/poison.h" 1#ifndef _LINUX_POISON_H
2#define _LINUX_POISON_H
3
4/********** include/linux/list.h **********/
5
6/*
7 * Architectures might want to move the poison pointer offset
8 * into some well-recognized area such as 0xdead000000000000,
9 * that is also not mappable by user-space exploits:
10 */
11#ifdef CONFIG_ILLEGAL_POINTER_VALUE
12# define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL)
13#else
14# define POISON_POINTER_DELTA 0
15#endif
16
17/*
18 * These are non-NULL pointers that will result in page faults
19 * under normal circumstances, used to verify that nobody uses
20 * non-initialized list entries.
21 */
22#define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA)
23#define LIST_POISON2 ((void *) 0x200 + POISON_POINTER_DELTA)
24
25/********** include/linux/timer.h **********/
26/*
27 * Magic number "tsta" to indicate a static timer initializer
28 * for the object debugging code.
29 */
30#define TIMER_ENTRY_STATIC ((void *) 0x300 + POISON_POINTER_DELTA)
31
32/********** mm/debug-pagealloc.c **********/
33#ifdef CONFIG_PAGE_POISONING_ZERO
34#define PAGE_POISON 0x00
35#else
36#define PAGE_POISON 0xaa
37#endif
38
39/********** mm/page_alloc.c ************/
40
41#define TAIL_MAPPING ((void *) 0x400 + POISON_POINTER_DELTA)
42
43/********** mm/slab.c **********/
44/*
45 * Magic nums for obj red zoning.
46 * Placed in the first word before and the first word after an obj.
47 */
48#define RED_INACTIVE 0x09F911029D74E35BULL /* when obj is inactive */
49#define RED_ACTIVE 0xD84156C5635688C0ULL /* when obj is active */
50
51#define SLUB_RED_INACTIVE 0xbb
52#define SLUB_RED_ACTIVE 0xcc
53
54/* ...and for poisoning */
55#define POISON_INUSE 0x5a /* for use-uninitialised poisoning */
56#define POISON_FREE 0x6b /* for use-after-free poisoning */
57#define POISON_END 0xa5 /* end-byte of poisoning */
58
59/********** arch/$ARCH/mm/init.c **********/
60#define POISON_FREE_INITMEM 0xcc
61
62/********** arch/ia64/hp/common/sba_iommu.c **********/
63/*
64 * arch/ia64/hp/common/sba_iommu.c uses a 16-byte poison string with a
65 * value of "SBAIOMMU POISON\0" for spill-over poisoning.
66 */
67
68/********** fs/jbd/journal.c **********/
69#define JBD_POISON_FREE 0x5b
70#define JBD2_POISON_FREE 0x5c
71
72/********** drivers/base/dmapool.c **********/
73#define POOL_POISON_FREED 0xa7 /* !inuse */
74#define POOL_POISON_ALLOCATED 0xa9 /* !initted */
75
76/********** drivers/atm/ **********/
77#define ATM_POISON_FREE 0x12
78#define ATM_POISON 0xdeadbeef
79
80/********** kernel/mutexes **********/
81#define MUTEX_DEBUG_INIT 0x11
82#define MUTEX_DEBUG_FREE 0x22
83
84/********** lib/flex_array.c **********/
85#define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */
86
87/********** security/ **********/
88#define KEY_DESTROY 0xbd
89
90#endif
diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h
index e26223f1f287..b96879477311 100644
--- a/tools/include/linux/string.h
+++ b/tools/include/linux/string.h
@@ -8,8 +8,10 @@ void *memdup(const void *src, size_t len);
8 8
9int strtobool(const char *s, bool *res); 9int strtobool(const char *s, bool *res);
10 10
11#ifndef __UCLIBC__ 11#ifdef __GLIBC__
12extern size_t strlcpy(char *dest, const char *src, size_t size); 12extern size_t strlcpy(char *dest, const char *src, size_t size);
13#endif 13#endif
14 14
15char *str_error_r(int errnum, char *buf, size_t buflen);
16
15#endif /* _LINUX_STRING_H_ */ 17#endif /* _LINUX_STRING_H_ */
diff --git a/tools/include/uapi/asm-generic/bitsperlong.h b/tools/include/uapi/asm-generic/bitsperlong.h
new file mode 100644
index 000000000000..23e6c416b85f
--- /dev/null
+++ b/tools/include/uapi/asm-generic/bitsperlong.h
@@ -0,0 +1,15 @@
1#ifndef _UAPI__ASM_GENERIC_BITS_PER_LONG
2#define _UAPI__ASM_GENERIC_BITS_PER_LONG
3
4/*
5 * There seems to be no way of detecting this automatically from user
6 * space, so 64 bit architectures should override this in their
7 * bitsperlong.h. In particular, an architecture that supports
8 * both 32 and 64 bit user space must not rely on CONFIG_64BIT
9 * to decide it, but rather check a compiler provided macro.
10 */
11#ifndef __BITS_PER_LONG
12#define __BITS_PER_LONG 32
13#endif
14
15#endif /* _UAPI__ASM_GENERIC_BITS_PER_LONG */
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
new file mode 100644
index 000000000000..406459b935a2
--- /dev/null
+++ b/tools/include/uapi/linux/bpf.h
@@ -0,0 +1,389 @@
1/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public
5 * License as published by the Free Software Foundation.
6 */
7#ifndef _UAPI__LINUX_BPF_H__
8#define _UAPI__LINUX_BPF_H__
9
10#include <linux/types.h>
11#include <linux/bpf_common.h>
12
13/* Extended instruction set based on top of classic BPF */
14
15/* instruction classes */
16#define BPF_ALU64 0x07 /* alu mode in double word width */
17
18/* ld/ldx fields */
19#define BPF_DW 0x18 /* double word */
20#define BPF_XADD 0xc0 /* exclusive add */
21
22/* alu/jmp fields */
23#define BPF_MOV 0xb0 /* mov reg to reg */
24#define BPF_ARSH 0xc0 /* sign extending arithmetic shift right */
25
26/* change endianness of a register */
27#define BPF_END 0xd0 /* flags for endianness conversion: */
28#define BPF_TO_LE 0x00 /* convert to little-endian */
29#define BPF_TO_BE 0x08 /* convert to big-endian */
30#define BPF_FROM_LE BPF_TO_LE
31#define BPF_FROM_BE BPF_TO_BE
32
33#define BPF_JNE 0x50 /* jump != */
34#define BPF_JSGT 0x60 /* SGT is signed '>', GT in x86 */
35#define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */
36#define BPF_CALL 0x80 /* function call */
37#define BPF_EXIT 0x90 /* function return */
38
39/* Register numbers */
40enum {
41 BPF_REG_0 = 0,
42 BPF_REG_1,
43 BPF_REG_2,
44 BPF_REG_3,
45 BPF_REG_4,
46 BPF_REG_5,
47 BPF_REG_6,
48 BPF_REG_7,
49 BPF_REG_8,
50 BPF_REG_9,
51 BPF_REG_10,
52 __MAX_BPF_REG,
53};
54
55/* BPF has 10 general purpose 64-bit registers and stack frame. */
56#define MAX_BPF_REG __MAX_BPF_REG
57
58struct bpf_insn {
59 __u8 code; /* opcode */
60 __u8 dst_reg:4; /* dest register */
61 __u8 src_reg:4; /* source register */
62 __s16 off; /* signed offset */
63 __s32 imm; /* signed immediate constant */
64};
65
66/* BPF syscall commands, see bpf(2) man-page for details. */
67enum bpf_cmd {
68 BPF_MAP_CREATE,
69 BPF_MAP_LOOKUP_ELEM,
70 BPF_MAP_UPDATE_ELEM,
71 BPF_MAP_DELETE_ELEM,
72 BPF_MAP_GET_NEXT_KEY,
73 BPF_PROG_LOAD,
74 BPF_OBJ_PIN,
75 BPF_OBJ_GET,
76};
77
78enum bpf_map_type {
79 BPF_MAP_TYPE_UNSPEC,
80 BPF_MAP_TYPE_HASH,
81 BPF_MAP_TYPE_ARRAY,
82 BPF_MAP_TYPE_PROG_ARRAY,
83 BPF_MAP_TYPE_PERF_EVENT_ARRAY,
84 BPF_MAP_TYPE_PERCPU_HASH,
85 BPF_MAP_TYPE_PERCPU_ARRAY,
86 BPF_MAP_TYPE_STACK_TRACE,
87};
88
89enum bpf_prog_type {
90 BPF_PROG_TYPE_UNSPEC,
91 BPF_PROG_TYPE_SOCKET_FILTER,
92 BPF_PROG_TYPE_KPROBE,
93 BPF_PROG_TYPE_SCHED_CLS,
94 BPF_PROG_TYPE_SCHED_ACT,
95 BPF_PROG_TYPE_TRACEPOINT,
96};
97
98#define BPF_PSEUDO_MAP_FD 1
99
100/* flags for BPF_MAP_UPDATE_ELEM command */
101#define BPF_ANY 0 /* create new element or update existing */
102#define BPF_NOEXIST 1 /* create new element if it didn't exist */
103#define BPF_EXIST 2 /* update existing element */
104
105#define BPF_F_NO_PREALLOC (1U << 0)
106
107union bpf_attr {
108 struct { /* anonymous struct used by BPF_MAP_CREATE command */
109 __u32 map_type; /* one of enum bpf_map_type */
110 __u32 key_size; /* size of key in bytes */
111 __u32 value_size; /* size of value in bytes */
112 __u32 max_entries; /* max number of entries in a map */
113 __u32 map_flags; /* prealloc or not */
114 };
115
116 struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
117 __u32 map_fd;
118 __aligned_u64 key;
119 union {
120 __aligned_u64 value;
121 __aligned_u64 next_key;
122 };
123 __u64 flags;
124 };
125
126 struct { /* anonymous struct used by BPF_PROG_LOAD command */
127 __u32 prog_type; /* one of enum bpf_prog_type */
128 __u32 insn_cnt;
129 __aligned_u64 insns;
130 __aligned_u64 license;
131 __u32 log_level; /* verbosity level of verifier */
132 __u32 log_size; /* size of user buffer */
133 __aligned_u64 log_buf; /* user supplied buffer */
134 __u32 kern_version; /* checked when prog_type=kprobe */
135 };
136
137 struct { /* anonymous struct used by BPF_OBJ_* commands */
138 __aligned_u64 pathname;
139 __u32 bpf_fd;
140 };
141} __attribute__((aligned(8)));
142
143/* integer value in 'imm' field of BPF_CALL instruction selects which helper
144 * function eBPF program intends to call
145 */
146enum bpf_func_id {
147 BPF_FUNC_unspec,
148 BPF_FUNC_map_lookup_elem, /* void *map_lookup_elem(&map, &key) */
149 BPF_FUNC_map_update_elem, /* int map_update_elem(&map, &key, &value, flags) */
150 BPF_FUNC_map_delete_elem, /* int map_delete_elem(&map, &key) */
151 BPF_FUNC_probe_read, /* int bpf_probe_read(void *dst, int size, void *src) */
152 BPF_FUNC_ktime_get_ns, /* u64 bpf_ktime_get_ns(void) */
153 BPF_FUNC_trace_printk, /* int bpf_trace_printk(const char *fmt, int fmt_size, ...) */
154 BPF_FUNC_get_prandom_u32, /* u32 prandom_u32(void) */
155 BPF_FUNC_get_smp_processor_id, /* u32 raw_smp_processor_id(void) */
156
157 /**
158 * skb_store_bytes(skb, offset, from, len, flags) - store bytes into packet
159 * @skb: pointer to skb
160 * @offset: offset within packet from skb->mac_header
161 * @from: pointer where to copy bytes from
162 * @len: number of bytes to store into packet
163 * @flags: bit 0 - if true, recompute skb->csum
164 * other bits - reserved
165 * Return: 0 on success
166 */
167 BPF_FUNC_skb_store_bytes,
168
169 /**
170 * l3_csum_replace(skb, offset, from, to, flags) - recompute IP checksum
171 * @skb: pointer to skb
172 * @offset: offset within packet where IP checksum is located
173 * @from: old value of header field
174 * @to: new value of header field
175 * @flags: bits 0-3 - size of header field
176 * other bits - reserved
177 * Return: 0 on success
178 */
179 BPF_FUNC_l3_csum_replace,
180
181 /**
182 * l4_csum_replace(skb, offset, from, to, flags) - recompute TCP/UDP checksum
183 * @skb: pointer to skb
184 * @offset: offset within packet where TCP/UDP checksum is located
185 * @from: old value of header field
186 * @to: new value of header field
187 * @flags: bits 0-3 - size of header field
188 * bit 4 - is pseudo header
189 * other bits - reserved
190 * Return: 0 on success
191 */
192 BPF_FUNC_l4_csum_replace,
193
194 /**
195 * bpf_tail_call(ctx, prog_array_map, index) - jump into another BPF program
196 * @ctx: context pointer passed to next program
197 * @prog_array_map: pointer to map which type is BPF_MAP_TYPE_PROG_ARRAY
198 * @index: index inside array that selects specific program to run
199 * Return: 0 on success
200 */
201 BPF_FUNC_tail_call,
202
203 /**
204 * bpf_clone_redirect(skb, ifindex, flags) - redirect to another netdev
205 * @skb: pointer to skb
206 * @ifindex: ifindex of the net device
207 * @flags: bit 0 - if set, redirect to ingress instead of egress
208 * other bits - reserved
209 * Return: 0 on success
210 */
211 BPF_FUNC_clone_redirect,
212
213 /**
214 * u64 bpf_get_current_pid_tgid(void)
215 * Return: current->tgid << 32 | current->pid
216 */
217 BPF_FUNC_get_current_pid_tgid,
218
219 /**
220 * u64 bpf_get_current_uid_gid(void)
221 * Return: current_gid << 32 | current_uid
222 */
223 BPF_FUNC_get_current_uid_gid,
224
225 /**
226 * bpf_get_current_comm(char *buf, int size_of_buf)
227 * stores current->comm into buf
228 * Return: 0 on success
229 */
230 BPF_FUNC_get_current_comm,
231
232 /**
233 * bpf_get_cgroup_classid(skb) - retrieve a proc's classid
234 * @skb: pointer to skb
235 * Return: classid if != 0
236 */
237 BPF_FUNC_get_cgroup_classid,
238 BPF_FUNC_skb_vlan_push, /* bpf_skb_vlan_push(skb, vlan_proto, vlan_tci) */
239 BPF_FUNC_skb_vlan_pop, /* bpf_skb_vlan_pop(skb) */
240
241 /**
242 * bpf_skb_[gs]et_tunnel_key(skb, key, size, flags)
243 * retrieve or populate tunnel metadata
244 * @skb: pointer to skb
245 * @key: pointer to 'struct bpf_tunnel_key'
246 * @size: size of 'struct bpf_tunnel_key'
247 * @flags: room for future extensions
248 * Retrun: 0 on success
249 */
250 BPF_FUNC_skb_get_tunnel_key,
251 BPF_FUNC_skb_set_tunnel_key,
252 BPF_FUNC_perf_event_read, /* u64 bpf_perf_event_read(&map, index) */
253 /**
254 * bpf_redirect(ifindex, flags) - redirect to another netdev
255 * @ifindex: ifindex of the net device
256 * @flags: bit 0 - if set, redirect to ingress instead of egress
257 * other bits - reserved
258 * Return: TC_ACT_REDIRECT
259 */
260 BPF_FUNC_redirect,
261
262 /**
263 * bpf_get_route_realm(skb) - retrieve a dst's tclassid
264 * @skb: pointer to skb
265 * Return: realm if != 0
266 */
267 BPF_FUNC_get_route_realm,
268
269 /**
270 * bpf_perf_event_output(ctx, map, index, data, size) - output perf raw sample
271 * @ctx: struct pt_regs*
272 * @map: pointer to perf_event_array map
273 * @index: index of event in the map
274 * @data: data on stack to be output as raw data
275 * @size: size of data
276 * Return: 0 on success
277 */
278 BPF_FUNC_perf_event_output,
279 BPF_FUNC_skb_load_bytes,
280
281 /**
282 * bpf_get_stackid(ctx, map, flags) - walk user or kernel stack and return id
283 * @ctx: struct pt_regs*
284 * @map: pointer to stack_trace map
285 * @flags: bits 0-7 - numer of stack frames to skip
286 * bit 8 - collect user stack instead of kernel
287 * bit 9 - compare stacks by hash only
288 * bit 10 - if two different stacks hash into the same stackid
289 * discard old
290 * other bits - reserved
291 * Return: >= 0 stackid on success or negative error
292 */
293 BPF_FUNC_get_stackid,
294
295 /**
296 * bpf_csum_diff(from, from_size, to, to_size, seed) - calculate csum diff
297 * @from: raw from buffer
298 * @from_size: length of from buffer
299 * @to: raw to buffer
300 * @to_size: length of to buffer
301 * @seed: optional seed
302 * Return: csum result
303 */
304 BPF_FUNC_csum_diff,
305
306 /**
307 * bpf_skb_[gs]et_tunnel_opt(skb, opt, size)
308 * retrieve or populate tunnel options metadata
309 * @skb: pointer to skb
310 * @opt: pointer to raw tunnel option data
311 * @size: size of @opt
312 * Return: 0 on success for set, option size for get
313 */
314 BPF_FUNC_skb_get_tunnel_opt,
315 BPF_FUNC_skb_set_tunnel_opt,
316 __BPF_FUNC_MAX_ID,
317};
318
319/* All flags used by eBPF helper functions, placed here. */
320
321/* BPF_FUNC_skb_store_bytes flags. */
322#define BPF_F_RECOMPUTE_CSUM (1ULL << 0)
323#define BPF_F_INVALIDATE_HASH (1ULL << 1)
324
325/* BPF_FUNC_l3_csum_replace and BPF_FUNC_l4_csum_replace flags.
326 * First 4 bits are for passing the header field size.
327 */
328#define BPF_F_HDR_FIELD_MASK 0xfULL
329
330/* BPF_FUNC_l4_csum_replace flags. */
331#define BPF_F_PSEUDO_HDR (1ULL << 4)
332#define BPF_F_MARK_MANGLED_0 (1ULL << 5)
333
334/* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */
335#define BPF_F_INGRESS (1ULL << 0)
336
337/* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
338#define BPF_F_TUNINFO_IPV6 (1ULL << 0)
339
340/* BPF_FUNC_get_stackid flags. */
341#define BPF_F_SKIP_FIELD_MASK 0xffULL
342#define BPF_F_USER_STACK (1ULL << 8)
343#define BPF_F_FAST_STACK_CMP (1ULL << 9)
344#define BPF_F_REUSE_STACKID (1ULL << 10)
345
346/* BPF_FUNC_skb_set_tunnel_key flags. */
347#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
348#define BPF_F_DONT_FRAGMENT (1ULL << 2)
349
350/* BPF_FUNC_perf_event_output flags. */
351#define BPF_F_INDEX_MASK 0xffffffffULL
352#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
353
354/* user accessible mirror of in-kernel sk_buff.
355 * new fields can only be added to the end of this structure
356 */
357struct __sk_buff {
358 __u32 len;
359 __u32 pkt_type;
360 __u32 mark;
361 __u32 queue_mapping;
362 __u32 protocol;
363 __u32 vlan_present;
364 __u32 vlan_tci;
365 __u32 vlan_proto;
366 __u32 priority;
367 __u32 ingress_ifindex;
368 __u32 ifindex;
369 __u32 tc_index;
370 __u32 cb[5];
371 __u32 hash;
372 __u32 tc_classid;
373 __u32 data;
374 __u32 data_end;
375};
376
377struct bpf_tunnel_key {
378 __u32 tunnel_id;
379 union {
380 __u32 remote_ipv4;
381 __u32 remote_ipv6[4];
382 };
383 __u8 tunnel_tos;
384 __u8 tunnel_ttl;
385 __u16 tunnel_ext;
386 __u32 tunnel_label;
387};
388
389#endif /* _UAPI__LINUX_BPF_H__ */
diff --git a/tools/include/uapi/linux/bpf_common.h b/tools/include/uapi/linux/bpf_common.h
new file mode 100644
index 000000000000..a5c220e0828f
--- /dev/null
+++ b/tools/include/uapi/linux/bpf_common.h
@@ -0,0 +1,55 @@
1#ifndef _UAPI__LINUX_BPF_COMMON_H__
2#define _UAPI__LINUX_BPF_COMMON_H__
3
4/* Instruction classes */
5#define BPF_CLASS(code) ((code) & 0x07)
6#define BPF_LD 0x00
7#define BPF_LDX 0x01
8#define BPF_ST 0x02
9#define BPF_STX 0x03
10#define BPF_ALU 0x04
11#define BPF_JMP 0x05
12#define BPF_RET 0x06
13#define BPF_MISC 0x07
14
15/* ld/ldx fields */
16#define BPF_SIZE(code) ((code) & 0x18)
17#define BPF_W 0x00
18#define BPF_H 0x08
19#define BPF_B 0x10
20#define BPF_MODE(code) ((code) & 0xe0)
21#define BPF_IMM 0x00
22#define BPF_ABS 0x20
23#define BPF_IND 0x40
24#define BPF_MEM 0x60
25#define BPF_LEN 0x80
26#define BPF_MSH 0xa0
27
28/* alu/jmp fields */
29#define BPF_OP(code) ((code) & 0xf0)
30#define BPF_ADD 0x00
31#define BPF_SUB 0x10
32#define BPF_MUL 0x20
33#define BPF_DIV 0x30
34#define BPF_OR 0x40
35#define BPF_AND 0x50
36#define BPF_LSH 0x60
37#define BPF_RSH 0x70
38#define BPF_NEG 0x80
39#define BPF_MOD 0x90
40#define BPF_XOR 0xa0
41
42#define BPF_JA 0x00
43#define BPF_JEQ 0x10
44#define BPF_JGT 0x20
45#define BPF_JGE 0x30
46#define BPF_JSET 0x40
47#define BPF_SRC(code) ((code) & 0x08)
48#define BPF_K 0x00
49#define BPF_X 0x08
50
51#ifndef BPF_MAXINSNS
52#define BPF_MAXINSNS 4096
53#endif
54
55#endif /* _UAPI__LINUX_BPF_COMMON_H__ */
diff --git a/tools/include/uapi/linux/hw_breakpoint.h b/tools/include/uapi/linux/hw_breakpoint.h
new file mode 100644
index 000000000000..b04000a2296a
--- /dev/null
+++ b/tools/include/uapi/linux/hw_breakpoint.h
@@ -0,0 +1,30 @@
1#ifndef _UAPI_LINUX_HW_BREAKPOINT_H
2#define _UAPI_LINUX_HW_BREAKPOINT_H
3
4enum {
5 HW_BREAKPOINT_LEN_1 = 1,
6 HW_BREAKPOINT_LEN_2 = 2,
7 HW_BREAKPOINT_LEN_4 = 4,
8 HW_BREAKPOINT_LEN_8 = 8,
9};
10
11enum {
12 HW_BREAKPOINT_EMPTY = 0,
13 HW_BREAKPOINT_R = 1,
14 HW_BREAKPOINT_W = 2,
15 HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W,
16 HW_BREAKPOINT_X = 4,
17 HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
18};
19
20enum bp_type_idx {
21 TYPE_INST = 0,
22#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
23 TYPE_DATA = 0,
24#else
25 TYPE_DATA = 1,
26#endif
27 TYPE_MAX
28};
29
30#endif /* _UAPI_LINUX_HW_BREAKPOINT_H */
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
new file mode 100644
index 000000000000..c66a485a24ac
--- /dev/null
+++ b/tools/include/uapi/linux/perf_event.h
@@ -0,0 +1,983 @@
1/*
2 * Performance events:
3 *
4 * Copyright (C) 2008-2009, Thomas Gleixner <tglx@linutronix.de>
5 * Copyright (C) 2008-2011, Red Hat, Inc., Ingo Molnar
6 * Copyright (C) 2008-2011, Red Hat, Inc., Peter Zijlstra
7 *
8 * Data type definitions, declarations, prototypes.
9 *
10 * Started by: Thomas Gleixner and Ingo Molnar
11 *
12 * For licencing details see kernel-base/COPYING
13 */
14#ifndef _UAPI_LINUX_PERF_EVENT_H
15#define _UAPI_LINUX_PERF_EVENT_H
16
17#include <linux/types.h>
18#include <linux/ioctl.h>
19#include <asm/byteorder.h>
20
21/*
22 * User-space ABI bits:
23 */
24
25/*
26 * attr.type
27 */
28enum perf_type_id {
29 PERF_TYPE_HARDWARE = 0,
30 PERF_TYPE_SOFTWARE = 1,
31 PERF_TYPE_TRACEPOINT = 2,
32 PERF_TYPE_HW_CACHE = 3,
33 PERF_TYPE_RAW = 4,
34 PERF_TYPE_BREAKPOINT = 5,
35
36 PERF_TYPE_MAX, /* non-ABI */
37};
38
39/*
40 * Generalized performance event event_id types, used by the
41 * attr.event_id parameter of the sys_perf_event_open()
42 * syscall:
43 */
44enum perf_hw_id {
45 /*
46 * Common hardware events, generalized by the kernel:
47 */
48 PERF_COUNT_HW_CPU_CYCLES = 0,
49 PERF_COUNT_HW_INSTRUCTIONS = 1,
50 PERF_COUNT_HW_CACHE_REFERENCES = 2,
51 PERF_COUNT_HW_CACHE_MISSES = 3,
52 PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
53 PERF_COUNT_HW_BRANCH_MISSES = 5,
54 PERF_COUNT_HW_BUS_CYCLES = 6,
55 PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
56 PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
57 PERF_COUNT_HW_REF_CPU_CYCLES = 9,
58
59 PERF_COUNT_HW_MAX, /* non-ABI */
60};
61
62/*
63 * Generalized hardware cache events:
64 *
65 * { L1-D, L1-I, LLC, ITLB, DTLB, BPU, NODE } x
66 * { read, write, prefetch } x
67 * { accesses, misses }
68 */
69enum perf_hw_cache_id {
70 PERF_COUNT_HW_CACHE_L1D = 0,
71 PERF_COUNT_HW_CACHE_L1I = 1,
72 PERF_COUNT_HW_CACHE_LL = 2,
73 PERF_COUNT_HW_CACHE_DTLB = 3,
74 PERF_COUNT_HW_CACHE_ITLB = 4,
75 PERF_COUNT_HW_CACHE_BPU = 5,
76 PERF_COUNT_HW_CACHE_NODE = 6,
77
78 PERF_COUNT_HW_CACHE_MAX, /* non-ABI */
79};
80
81enum perf_hw_cache_op_id {
82 PERF_COUNT_HW_CACHE_OP_READ = 0,
83 PERF_COUNT_HW_CACHE_OP_WRITE = 1,
84 PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
85
86 PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */
87};
88
89enum perf_hw_cache_op_result_id {
90 PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
91 PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
92
93 PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */
94};
95
96/*
97 * Special "software" events provided by the kernel, even if the hardware
98 * does not support performance events. These events measure various
99 * physical and sw events of the kernel (and allow the profiling of them as
100 * well):
101 */
102enum perf_sw_ids {
103 PERF_COUNT_SW_CPU_CLOCK = 0,
104 PERF_COUNT_SW_TASK_CLOCK = 1,
105 PERF_COUNT_SW_PAGE_FAULTS = 2,
106 PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
107 PERF_COUNT_SW_CPU_MIGRATIONS = 4,
108 PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
109 PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
110 PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
111 PERF_COUNT_SW_EMULATION_FAULTS = 8,
112 PERF_COUNT_SW_DUMMY = 9,
113 PERF_COUNT_SW_BPF_OUTPUT = 10,
114
115 PERF_COUNT_SW_MAX, /* non-ABI */
116};
117
118/*
119 * Bits that can be set in attr.sample_type to request information
120 * in the overflow packets.
121 */
122enum perf_event_sample_format {
123 PERF_SAMPLE_IP = 1U << 0,
124 PERF_SAMPLE_TID = 1U << 1,
125 PERF_SAMPLE_TIME = 1U << 2,
126 PERF_SAMPLE_ADDR = 1U << 3,
127 PERF_SAMPLE_READ = 1U << 4,
128 PERF_SAMPLE_CALLCHAIN = 1U << 5,
129 PERF_SAMPLE_ID = 1U << 6,
130 PERF_SAMPLE_CPU = 1U << 7,
131 PERF_SAMPLE_PERIOD = 1U << 8,
132 PERF_SAMPLE_STREAM_ID = 1U << 9,
133 PERF_SAMPLE_RAW = 1U << 10,
134 PERF_SAMPLE_BRANCH_STACK = 1U << 11,
135 PERF_SAMPLE_REGS_USER = 1U << 12,
136 PERF_SAMPLE_STACK_USER = 1U << 13,
137 PERF_SAMPLE_WEIGHT = 1U << 14,
138 PERF_SAMPLE_DATA_SRC = 1U << 15,
139 PERF_SAMPLE_IDENTIFIER = 1U << 16,
140 PERF_SAMPLE_TRANSACTION = 1U << 17,
141 PERF_SAMPLE_REGS_INTR = 1U << 18,
142
143 PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */
144};
145
146/*
147 * values to program into branch_sample_type when PERF_SAMPLE_BRANCH is set
148 *
149 * If the user does not pass priv level information via branch_sample_type,
150 * the kernel uses the event's priv level. Branch and event priv levels do
151 * not have to match. Branch priv level is checked for permissions.
152 *
153 * The branch types can be combined, however BRANCH_ANY covers all types
154 * of branches and therefore it supersedes all the other types.
155 */
156enum perf_branch_sample_type_shift {
157 PERF_SAMPLE_BRANCH_USER_SHIFT = 0, /* user branches */
158 PERF_SAMPLE_BRANCH_KERNEL_SHIFT = 1, /* kernel branches */
159 PERF_SAMPLE_BRANCH_HV_SHIFT = 2, /* hypervisor branches */
160
161 PERF_SAMPLE_BRANCH_ANY_SHIFT = 3, /* any branch types */
162 PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT = 4, /* any call branch */
163 PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT = 5, /* any return branch */
164 PERF_SAMPLE_BRANCH_IND_CALL_SHIFT = 6, /* indirect calls */
165 PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT = 7, /* transaction aborts */
166 PERF_SAMPLE_BRANCH_IN_TX_SHIFT = 8, /* in transaction */
167 PERF_SAMPLE_BRANCH_NO_TX_SHIFT = 9, /* not in transaction */
168 PERF_SAMPLE_BRANCH_COND_SHIFT = 10, /* conditional branches */
169
170 PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT = 11, /* call/ret stack */
171 PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT = 12, /* indirect jumps */
172 PERF_SAMPLE_BRANCH_CALL_SHIFT = 13, /* direct call */
173
174 PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 14, /* no flags */
175 PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 15, /* no cycles */
176
177 PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */
178};
179
180enum perf_branch_sample_type {
181 PERF_SAMPLE_BRANCH_USER = 1U << PERF_SAMPLE_BRANCH_USER_SHIFT,
182 PERF_SAMPLE_BRANCH_KERNEL = 1U << PERF_SAMPLE_BRANCH_KERNEL_SHIFT,
183 PERF_SAMPLE_BRANCH_HV = 1U << PERF_SAMPLE_BRANCH_HV_SHIFT,
184
185 PERF_SAMPLE_BRANCH_ANY = 1U << PERF_SAMPLE_BRANCH_ANY_SHIFT,
186 PERF_SAMPLE_BRANCH_ANY_CALL = 1U << PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT,
187 PERF_SAMPLE_BRANCH_ANY_RETURN = 1U << PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT,
188 PERF_SAMPLE_BRANCH_IND_CALL = 1U << PERF_SAMPLE_BRANCH_IND_CALL_SHIFT,
189 PERF_SAMPLE_BRANCH_ABORT_TX = 1U << PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT,
190 PERF_SAMPLE_BRANCH_IN_TX = 1U << PERF_SAMPLE_BRANCH_IN_TX_SHIFT,
191 PERF_SAMPLE_BRANCH_NO_TX = 1U << PERF_SAMPLE_BRANCH_NO_TX_SHIFT,
192 PERF_SAMPLE_BRANCH_COND = 1U << PERF_SAMPLE_BRANCH_COND_SHIFT,
193
194 PERF_SAMPLE_BRANCH_CALL_STACK = 1U << PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT,
195 PERF_SAMPLE_BRANCH_IND_JUMP = 1U << PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT,
196 PERF_SAMPLE_BRANCH_CALL = 1U << PERF_SAMPLE_BRANCH_CALL_SHIFT,
197
198 PERF_SAMPLE_BRANCH_NO_FLAGS = 1U << PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT,
199 PERF_SAMPLE_BRANCH_NO_CYCLES = 1U << PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT,
200
201 PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
202};
203
204#define PERF_SAMPLE_BRANCH_PLM_ALL \
205 (PERF_SAMPLE_BRANCH_USER|\
206 PERF_SAMPLE_BRANCH_KERNEL|\
207 PERF_SAMPLE_BRANCH_HV)
208
209/*
210 * Values to determine ABI of the registers dump.
211 */
212enum perf_sample_regs_abi {
213 PERF_SAMPLE_REGS_ABI_NONE = 0,
214 PERF_SAMPLE_REGS_ABI_32 = 1,
215 PERF_SAMPLE_REGS_ABI_64 = 2,
216};
217
218/*
219 * Values for the memory transaction event qualifier, mostly for
220 * abort events. Multiple bits can be set.
221 */
222enum {
223 PERF_TXN_ELISION = (1 << 0), /* From elision */
224 PERF_TXN_TRANSACTION = (1 << 1), /* From transaction */
225 PERF_TXN_SYNC = (1 << 2), /* Instruction is related */
226 PERF_TXN_ASYNC = (1 << 3), /* Instruction not related */
227 PERF_TXN_RETRY = (1 << 4), /* Retry possible */
228 PERF_TXN_CONFLICT = (1 << 5), /* Conflict abort */
229 PERF_TXN_CAPACITY_WRITE = (1 << 6), /* Capacity write abort */
230 PERF_TXN_CAPACITY_READ = (1 << 7), /* Capacity read abort */
231
232 PERF_TXN_MAX = (1 << 8), /* non-ABI */
233
234 /* bits 32..63 are reserved for the abort code */
235
236 PERF_TXN_ABORT_MASK = (0xffffffffULL << 32),
237 PERF_TXN_ABORT_SHIFT = 32,
238};
239
240/*
241 * The format of the data returned by read() on a perf event fd,
242 * as specified by attr.read_format:
243 *
244 * struct read_format {
245 * { u64 value;
246 * { u64 time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
247 * { u64 time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
248 * { u64 id; } && PERF_FORMAT_ID
249 * } && !PERF_FORMAT_GROUP
250 *
251 * { u64 nr;
252 * { u64 time_enabled; } && PERF_FORMAT_TOTAL_TIME_ENABLED
253 * { u64 time_running; } && PERF_FORMAT_TOTAL_TIME_RUNNING
254 * { u64 value;
255 * { u64 id; } && PERF_FORMAT_ID
256 * } cntr[nr];
257 * } && PERF_FORMAT_GROUP
258 * };
259 */
260enum perf_event_read_format {
261 PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
262 PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
263 PERF_FORMAT_ID = 1U << 2,
264 PERF_FORMAT_GROUP = 1U << 3,
265
266 PERF_FORMAT_MAX = 1U << 4, /* non-ABI */
267};
268
269#define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */
270#define PERF_ATTR_SIZE_VER1 72 /* add: config2 */
271#define PERF_ATTR_SIZE_VER2 80 /* add: branch_sample_type */
272#define PERF_ATTR_SIZE_VER3 96 /* add: sample_regs_user */
273 /* add: sample_stack_user */
274#define PERF_ATTR_SIZE_VER4 104 /* add: sample_regs_intr */
275#define PERF_ATTR_SIZE_VER5 112 /* add: aux_watermark */
276
277/*
278 * Hardware event_id to monitor via a performance monitoring event:
279 *
280 * @sample_max_stack: Max number of frame pointers in a callchain,
281 * should be < /proc/sys/kernel/perf_event_max_stack
282 */
283struct perf_event_attr {
284
285 /*
286 * Major type: hardware/software/tracepoint/etc.
287 */
288 __u32 type;
289
290 /*
291 * Size of the attr structure, for fwd/bwd compat.
292 */
293 __u32 size;
294
295 /*
296 * Type specific configuration information.
297 */
298 __u64 config;
299
300 union {
301 __u64 sample_period;
302 __u64 sample_freq;
303 };
304
305 __u64 sample_type;
306 __u64 read_format;
307
308 __u64 disabled : 1, /* off by default */
309 inherit : 1, /* children inherit it */
310 pinned : 1, /* must always be on PMU */
311 exclusive : 1, /* only group on PMU */
312 exclude_user : 1, /* don't count user */
313 exclude_kernel : 1, /* ditto kernel */
314 exclude_hv : 1, /* ditto hypervisor */
315 exclude_idle : 1, /* don't count when idle */
316 mmap : 1, /* include mmap data */
317 comm : 1, /* include comm data */
318 freq : 1, /* use freq, not period */
319 inherit_stat : 1, /* per task counts */
320 enable_on_exec : 1, /* next exec enables */
321 task : 1, /* trace fork/exit */
322 watermark : 1, /* wakeup_watermark */
323 /*
324 * precise_ip:
325 *
326 * 0 - SAMPLE_IP can have arbitrary skid
327 * 1 - SAMPLE_IP must have constant skid
328 * 2 - SAMPLE_IP requested to have 0 skid
329 * 3 - SAMPLE_IP must have 0 skid
330 *
331 * See also PERF_RECORD_MISC_EXACT_IP
332 */
333 precise_ip : 2, /* skid constraint */
334 mmap_data : 1, /* non-exec mmap data */
335 sample_id_all : 1, /* sample_type all events */
336
337 exclude_host : 1, /* don't count in host */
338 exclude_guest : 1, /* don't count in guest */
339
340 exclude_callchain_kernel : 1, /* exclude kernel callchains */
341 exclude_callchain_user : 1, /* exclude user callchains */
342 mmap2 : 1, /* include mmap with inode data */
343 comm_exec : 1, /* flag comm events that are due to an exec */
344 use_clockid : 1, /* use @clockid for time fields */
345 context_switch : 1, /* context switch data */
346 write_backward : 1, /* Write ring buffer from end to beginning */
347 __reserved_1 : 36;
348
349 union {
350 __u32 wakeup_events; /* wakeup every n events */
351 __u32 wakeup_watermark; /* bytes before wakeup */
352 };
353
354 __u32 bp_type;
355 union {
356 __u64 bp_addr;
357 __u64 config1; /* extension of config */
358 };
359 union {
360 __u64 bp_len;
361 __u64 config2; /* extension of config1 */
362 };
363 __u64 branch_sample_type; /* enum perf_branch_sample_type */
364
365 /*
366 * Defines set of user regs to dump on samples.
367 * See asm/perf_regs.h for details.
368 */
369 __u64 sample_regs_user;
370
371 /*
372 * Defines size of the user stack to dump on samples.
373 */
374 __u32 sample_stack_user;
375
376 __s32 clockid;
377 /*
378 * Defines set of regs to dump for each sample
379 * state captured on:
380 * - precise = 0: PMU interrupt
381 * - precise > 0: sampled instruction
382 *
383 * See asm/perf_regs.h for details.
384 */
385 __u64 sample_regs_intr;
386
387 /*
388 * Wakeup watermark for AUX area
389 */
390 __u32 aux_watermark;
391 __u16 sample_max_stack;
392 __u16 __reserved_2; /* align to __u64 */
393};
394
395#define perf_flags(attr) (*(&(attr)->read_format + 1))
396
397/*
398 * Ioctls that can be done on a perf event fd:
399 */
400#define PERF_EVENT_IOC_ENABLE _IO ('$', 0)
401#define PERF_EVENT_IOC_DISABLE _IO ('$', 1)
402#define PERF_EVENT_IOC_REFRESH _IO ('$', 2)
403#define PERF_EVENT_IOC_RESET _IO ('$', 3)
404#define PERF_EVENT_IOC_PERIOD _IOW('$', 4, __u64)
405#define PERF_EVENT_IOC_SET_OUTPUT _IO ('$', 5)
406#define PERF_EVENT_IOC_SET_FILTER _IOW('$', 6, char *)
407#define PERF_EVENT_IOC_ID _IOR('$', 7, __u64 *)
408#define PERF_EVENT_IOC_SET_BPF _IOW('$', 8, __u32)
409#define PERF_EVENT_IOC_PAUSE_OUTPUT _IOW('$', 9, __u32)
410
411enum perf_event_ioc_flags {
412 PERF_IOC_FLAG_GROUP = 1U << 0,
413};
414
415/*
416 * Structure of the page that can be mapped via mmap
417 */
418struct perf_event_mmap_page {
419 __u32 version; /* version number of this structure */
420 __u32 compat_version; /* lowest version this is compat with */
421
422 /*
423 * Bits needed to read the hw events in user-space.
424 *
425 * u32 seq, time_mult, time_shift, index, width;
426 * u64 count, enabled, running;
427 * u64 cyc, time_offset;
428 * s64 pmc = 0;
429 *
430 * do {
431 * seq = pc->lock;
432 * barrier()
433 *
434 * enabled = pc->time_enabled;
435 * running = pc->time_running;
436 *
437 * if (pc->cap_usr_time && enabled != running) {
438 * cyc = rdtsc();
439 * time_offset = pc->time_offset;
440 * time_mult = pc->time_mult;
441 * time_shift = pc->time_shift;
442 * }
443 *
444 * index = pc->index;
445 * count = pc->offset;
446 * if (pc->cap_user_rdpmc && index) {
447 * width = pc->pmc_width;
448 * pmc = rdpmc(index - 1);
449 * }
450 *
451 * barrier();
452 * } while (pc->lock != seq);
453 *
454 * NOTE: for obvious reason this only works on self-monitoring
455 * processes.
456 */
457 __u32 lock; /* seqlock for synchronization */
458 __u32 index; /* hardware event identifier */
459 __s64 offset; /* add to hardware event value */
460 __u64 time_enabled; /* time event active */
461 __u64 time_running; /* time event on cpu */
462 union {
463 __u64 capabilities;
464 struct {
465 __u64 cap_bit0 : 1, /* Always 0, deprecated, see commit 860f085b74e9 */
466 cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */
467
468 cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */
469 cap_user_time : 1, /* The time_* fields are used */
470 cap_user_time_zero : 1, /* The time_zero field is used */
471 cap_____res : 59;
472 };
473 };
474
475 /*
476 * If cap_user_rdpmc this field provides the bit-width of the value
477 * read using the rdpmc() or equivalent instruction. This can be used
478 * to sign extend the result like:
479 *
480 * pmc <<= 64 - width;
481 * pmc >>= 64 - width; // signed shift right
482 * count += pmc;
483 */
484 __u16 pmc_width;
485
486 /*
487 * If cap_usr_time the below fields can be used to compute the time
488 * delta since time_enabled (in ns) using rdtsc or similar.
489 *
490 * u64 quot, rem;
491 * u64 delta;
492 *
493 * quot = (cyc >> time_shift);
494 * rem = cyc & (((u64)1 << time_shift) - 1);
495 * delta = time_offset + quot * time_mult +
496 * ((rem * time_mult) >> time_shift);
497 *
498 * Where time_offset,time_mult,time_shift and cyc are read in the
499 * seqcount loop described above. This delta can then be added to
500 * enabled and possible running (if index), improving the scaling:
501 *
502 * enabled += delta;
503 * if (index)
504 * running += delta;
505 *
506 * quot = count / running;
507 * rem = count % running;
508 * count = quot * enabled + (rem * enabled) / running;
509 */
510 __u16 time_shift;
511 __u32 time_mult;
512 __u64 time_offset;
513 /*
514 * If cap_usr_time_zero, the hardware clock (e.g. TSC) can be calculated
515 * from sample timestamps.
516 *
517 * time = timestamp - time_zero;
518 * quot = time / time_mult;
519 * rem = time % time_mult;
520 * cyc = (quot << time_shift) + (rem << time_shift) / time_mult;
521 *
522 * And vice versa:
523 *
524 * quot = cyc >> time_shift;
525 * rem = cyc & (((u64)1 << time_shift) - 1);
526 * timestamp = time_zero + quot * time_mult +
527 * ((rem * time_mult) >> time_shift);
528 */
529 __u64 time_zero;
530 __u32 size; /* Header size up to __reserved[] fields. */
531
532 /*
533 * Hole for extension of the self monitor capabilities
534 */
535
536 __u8 __reserved[118*8+4]; /* align to 1k. */
537
538 /*
539 * Control data for the mmap() data buffer.
540 *
541 * User-space reading the @data_head value should issue an smp_rmb(),
542 * after reading this value.
543 *
544 * When the mapping is PROT_WRITE the @data_tail value should be
545 * written by userspace to reflect the last read data, after issueing
546 * an smp_mb() to separate the data read from the ->data_tail store.
547 * In this case the kernel will not over-write unread data.
548 *
549 * See perf_output_put_handle() for the data ordering.
550 *
551 * data_{offset,size} indicate the location and size of the perf record
552 * buffer within the mmapped area.
553 */
554 __u64 data_head; /* head in the data section */
555 __u64 data_tail; /* user-space written tail */
556 __u64 data_offset; /* where the buffer starts */
557 __u64 data_size; /* data buffer size */
558
559 /*
560 * AUX area is defined by aux_{offset,size} fields that should be set
561 * by the userspace, so that
562 *
563 * aux_offset >= data_offset + data_size
564 *
565 * prior to mmap()ing it. Size of the mmap()ed area should be aux_size.
566 *
567 * Ring buffer pointers aux_{head,tail} have the same semantics as
568 * data_{head,tail} and same ordering rules apply.
569 */
570 __u64 aux_head;
571 __u64 aux_tail;
572 __u64 aux_offset;
573 __u64 aux_size;
574};
575
576#define PERF_RECORD_MISC_CPUMODE_MASK (7 << 0)
577#define PERF_RECORD_MISC_CPUMODE_UNKNOWN (0 << 0)
578#define PERF_RECORD_MISC_KERNEL (1 << 0)
579#define PERF_RECORD_MISC_USER (2 << 0)
580#define PERF_RECORD_MISC_HYPERVISOR (3 << 0)
581#define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0)
582#define PERF_RECORD_MISC_GUEST_USER (5 << 0)
583
584/*
585 * Indicates that /proc/PID/maps parsing are truncated by time out.
586 */
587#define PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT (1 << 12)
588/*
589 * PERF_RECORD_MISC_MMAP_DATA and PERF_RECORD_MISC_COMM_EXEC are used on
590 * different events so can reuse the same bit position.
591 * Ditto PERF_RECORD_MISC_SWITCH_OUT.
592 */
593#define PERF_RECORD_MISC_MMAP_DATA (1 << 13)
594#define PERF_RECORD_MISC_COMM_EXEC (1 << 13)
595#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)
596/*
597 * Indicates that the content of PERF_SAMPLE_IP points to
598 * the actual instruction that triggered the event. See also
599 * perf_event_attr::precise_ip.
600 */
601#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
602/*
603 * Reserve the last bit to indicate some extended misc field
604 */
605#define PERF_RECORD_MISC_EXT_RESERVED (1 << 15)
606
607struct perf_event_header {
608 __u32 type;
609 __u16 misc;
610 __u16 size;
611};
612
613enum perf_event_type {
614
615 /*
616 * If perf_event_attr.sample_id_all is set then all event types will
617 * have the sample_type selected fields related to where/when
618 * (identity) an event took place (TID, TIME, ID, STREAM_ID, CPU,
619 * IDENTIFIER) described in PERF_RECORD_SAMPLE below, it will be stashed
620 * just after the perf_event_header and the fields already present for
621 * the existing fields, i.e. at the end of the payload. That way a newer
622 * perf.data file will be supported by older perf tools, with these new
623 * optional fields being ignored.
624 *
625 * struct sample_id {
626 * { u32 pid, tid; } && PERF_SAMPLE_TID
627 * { u64 time; } && PERF_SAMPLE_TIME
628 * { u64 id; } && PERF_SAMPLE_ID
629 * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
630 * { u32 cpu, res; } && PERF_SAMPLE_CPU
631 * { u64 id; } && PERF_SAMPLE_IDENTIFIER
632 * } && perf_event_attr::sample_id_all
633 *
634 * Note that PERF_SAMPLE_IDENTIFIER duplicates PERF_SAMPLE_ID. The
635 * advantage of PERF_SAMPLE_IDENTIFIER is that its position is fixed
636 * relative to header.size.
637 */
638
639 /*
640 * The MMAP events record the PROT_EXEC mappings so that we can
641 * correlate userspace IPs to code. They have the following structure:
642 *
643 * struct {
644 * struct perf_event_header header;
645 *
646 * u32 pid, tid;
647 * u64 addr;
648 * u64 len;
649 * u64 pgoff;
650 * char filename[];
651 * struct sample_id sample_id;
652 * };
653 */
654 PERF_RECORD_MMAP = 1,
655
656 /*
657 * struct {
658 * struct perf_event_header header;
659 * u64 id;
660 * u64 lost;
661 * struct sample_id sample_id;
662 * };
663 */
664 PERF_RECORD_LOST = 2,
665
666 /*
667 * struct {
668 * struct perf_event_header header;
669 *
670 * u32 pid, tid;
671 * char comm[];
672 * struct sample_id sample_id;
673 * };
674 */
675 PERF_RECORD_COMM = 3,
676
677 /*
678 * struct {
679 * struct perf_event_header header;
680 * u32 pid, ppid;
681 * u32 tid, ptid;
682 * u64 time;
683 * struct sample_id sample_id;
684 * };
685 */
686 PERF_RECORD_EXIT = 4,
687
688 /*
689 * struct {
690 * struct perf_event_header header;
691 * u64 time;
692 * u64 id;
693 * u64 stream_id;
694 * struct sample_id sample_id;
695 * };
696 */
697 PERF_RECORD_THROTTLE = 5,
698 PERF_RECORD_UNTHROTTLE = 6,
699
700 /*
701 * struct {
702 * struct perf_event_header header;
703 * u32 pid, ppid;
704 * u32 tid, ptid;
705 * u64 time;
706 * struct sample_id sample_id;
707 * };
708 */
709 PERF_RECORD_FORK = 7,
710
711 /*
712 * struct {
713 * struct perf_event_header header;
714 * u32 pid, tid;
715 *
716 * struct read_format values;
717 * struct sample_id sample_id;
718 * };
719 */
720 PERF_RECORD_READ = 8,
721
722 /*
723 * struct {
724 * struct perf_event_header header;
725 *
726 * #
727 * # Note that PERF_SAMPLE_IDENTIFIER duplicates PERF_SAMPLE_ID.
728 * # The advantage of PERF_SAMPLE_IDENTIFIER is that its position
729 * # is fixed relative to header.
730 * #
731 *
732 * { u64 id; } && PERF_SAMPLE_IDENTIFIER
733 * { u64 ip; } && PERF_SAMPLE_IP
734 * { u32 pid, tid; } && PERF_SAMPLE_TID
735 * { u64 time; } && PERF_SAMPLE_TIME
736 * { u64 addr; } && PERF_SAMPLE_ADDR
737 * { u64 id; } && PERF_SAMPLE_ID
738 * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
739 * { u32 cpu, res; } && PERF_SAMPLE_CPU
740 * { u64 period; } && PERF_SAMPLE_PERIOD
741 *
742 * { struct read_format values; } && PERF_SAMPLE_READ
743 *
744 * { u64 nr,
745 * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
746 *
747 * #
748 * # The RAW record below is opaque data wrt the ABI
749 * #
750 * # That is, the ABI doesn't make any promises wrt to
751 * # the stability of its content, it may vary depending
752 * # on event, hardware, kernel version and phase of
753 * # the moon.
754 * #
755 * # In other words, PERF_SAMPLE_RAW contents are not an ABI.
756 * #
757 *
758 * { u32 size;
759 * char data[size];}&& PERF_SAMPLE_RAW
760 *
761 * { u64 nr;
762 * { u64 from, to, flags } lbr[nr];} && PERF_SAMPLE_BRANCH_STACK
763 *
764 * { u64 abi; # enum perf_sample_regs_abi
765 * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER
766 *
767 * { u64 size;
768 * char data[size];
769 * u64 dyn_size; } && PERF_SAMPLE_STACK_USER
770 *
771 * { u64 weight; } && PERF_SAMPLE_WEIGHT
772 * { u64 data_src; } && PERF_SAMPLE_DATA_SRC
773 * { u64 transaction; } && PERF_SAMPLE_TRANSACTION
774 * { u64 abi; # enum perf_sample_regs_abi
775 * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR
776 * };
777 */
778 PERF_RECORD_SAMPLE = 9,
779
780 /*
781 * The MMAP2 records are an augmented version of MMAP, they add
782 * maj, min, ino numbers to be used to uniquely identify each mapping
783 *
784 * struct {
785 * struct perf_event_header header;
786 *
787 * u32 pid, tid;
788 * u64 addr;
789 * u64 len;
790 * u64 pgoff;
791 * u32 maj;
792 * u32 min;
793 * u64 ino;
794 * u64 ino_generation;
795 * u32 prot, flags;
796 * char filename[];
797 * struct sample_id sample_id;
798 * };
799 */
800 PERF_RECORD_MMAP2 = 10,
801
802 /*
803 * Records that new data landed in the AUX buffer part.
804 *
805 * struct {
806 * struct perf_event_header header;
807 *
808 * u64 aux_offset;
809 * u64 aux_size;
810 * u64 flags;
811 * struct sample_id sample_id;
812 * };
813 */
814 PERF_RECORD_AUX = 11,
815
816 /*
817 * Indicates that instruction trace has started
818 *
819 * struct {
820 * struct perf_event_header header;
821 * u32 pid;
822 * u32 tid;
823 * };
824 */
825 PERF_RECORD_ITRACE_START = 12,
826
827 /*
828 * Records the dropped/lost sample number.
829 *
830 * struct {
831 * struct perf_event_header header;
832 *
833 * u64 lost;
834 * struct sample_id sample_id;
835 * };
836 */
837 PERF_RECORD_LOST_SAMPLES = 13,
838
839 /*
840 * Records a context switch in or out (flagged by
841 * PERF_RECORD_MISC_SWITCH_OUT). See also
842 * PERF_RECORD_SWITCH_CPU_WIDE.
843 *
844 * struct {
845 * struct perf_event_header header;
846 * struct sample_id sample_id;
847 * };
848 */
849 PERF_RECORD_SWITCH = 14,
850
851 /*
852 * CPU-wide version of PERF_RECORD_SWITCH with next_prev_pid and
853 * next_prev_tid that are the next (switching out) or previous
854 * (switching in) pid/tid.
855 *
856 * struct {
857 * struct perf_event_header header;
858 * u32 next_prev_pid;
859 * u32 next_prev_tid;
860 * struct sample_id sample_id;
861 * };
862 */
863 PERF_RECORD_SWITCH_CPU_WIDE = 15,
864
865 PERF_RECORD_MAX, /* non-ABI */
866};
867
868#define PERF_MAX_STACK_DEPTH 127
869#define PERF_MAX_CONTEXTS_PER_STACK 8
870
871enum perf_callchain_context {
872 PERF_CONTEXT_HV = (__u64)-32,
873 PERF_CONTEXT_KERNEL = (__u64)-128,
874 PERF_CONTEXT_USER = (__u64)-512,
875
876 PERF_CONTEXT_GUEST = (__u64)-2048,
877 PERF_CONTEXT_GUEST_KERNEL = (__u64)-2176,
878 PERF_CONTEXT_GUEST_USER = (__u64)-2560,
879
880 PERF_CONTEXT_MAX = (__u64)-4095,
881};
882
883/**
884 * PERF_RECORD_AUX::flags bits
885 */
886#define PERF_AUX_FLAG_TRUNCATED 0x01 /* record was truncated to fit */
887#define PERF_AUX_FLAG_OVERWRITE 0x02 /* snapshot from overwrite mode */
888
889#define PERF_FLAG_FD_NO_GROUP (1UL << 0)
890#define PERF_FLAG_FD_OUTPUT (1UL << 1)
891#define PERF_FLAG_PID_CGROUP (1UL << 2) /* pid=cgroup id, per-cpu mode only */
892#define PERF_FLAG_FD_CLOEXEC (1UL << 3) /* O_CLOEXEC */
893
894union perf_mem_data_src {
895 __u64 val;
896 struct {
897 __u64 mem_op:5, /* type of opcode */
898 mem_lvl:14, /* memory hierarchy level */
899 mem_snoop:5, /* snoop mode */
900 mem_lock:2, /* lock instr */
901 mem_dtlb:7, /* tlb access */
902 mem_rsvd:31;
903 };
904};
905
906/* type of opcode (load/store/prefetch,code) */
907#define PERF_MEM_OP_NA 0x01 /* not available */
908#define PERF_MEM_OP_LOAD 0x02 /* load instruction */
909#define PERF_MEM_OP_STORE 0x04 /* store instruction */
910#define PERF_MEM_OP_PFETCH 0x08 /* prefetch */
911#define PERF_MEM_OP_EXEC 0x10 /* code (execution) */
912#define PERF_MEM_OP_SHIFT 0
913
914/* memory hierarchy (memory level, hit or miss) */
915#define PERF_MEM_LVL_NA 0x01 /* not available */
916#define PERF_MEM_LVL_HIT 0x02 /* hit level */
917#define PERF_MEM_LVL_MISS 0x04 /* miss level */
918#define PERF_MEM_LVL_L1 0x08 /* L1 */
919#define PERF_MEM_LVL_LFB 0x10 /* Line Fill Buffer */
920#define PERF_MEM_LVL_L2 0x20 /* L2 */
921#define PERF_MEM_LVL_L3 0x40 /* L3 */
922#define PERF_MEM_LVL_LOC_RAM 0x80 /* Local DRAM */
923#define PERF_MEM_LVL_REM_RAM1 0x100 /* Remote DRAM (1 hop) */
924#define PERF_MEM_LVL_REM_RAM2 0x200 /* Remote DRAM (2 hops) */
925#define PERF_MEM_LVL_REM_CCE1 0x400 /* Remote Cache (1 hop) */
926#define PERF_MEM_LVL_REM_CCE2 0x800 /* Remote Cache (2 hops) */
927#define PERF_MEM_LVL_IO 0x1000 /* I/O memory */
928#define PERF_MEM_LVL_UNC 0x2000 /* Uncached memory */
929#define PERF_MEM_LVL_SHIFT 5
930
931/* snoop mode */
932#define PERF_MEM_SNOOP_NA 0x01 /* not available */
933#define PERF_MEM_SNOOP_NONE 0x02 /* no snoop */
934#define PERF_MEM_SNOOP_HIT 0x04 /* snoop hit */
935#define PERF_MEM_SNOOP_MISS 0x08 /* snoop miss */
936#define PERF_MEM_SNOOP_HITM 0x10 /* snoop hit modified */
937#define PERF_MEM_SNOOP_SHIFT 19
938
939/* locked instruction */
940#define PERF_MEM_LOCK_NA 0x01 /* not available */
941#define PERF_MEM_LOCK_LOCKED 0x02 /* locked transaction */
942#define PERF_MEM_LOCK_SHIFT 24
943
944/* TLB access */
945#define PERF_MEM_TLB_NA 0x01 /* not available */
946#define PERF_MEM_TLB_HIT 0x02 /* hit level */
947#define PERF_MEM_TLB_MISS 0x04 /* miss level */
948#define PERF_MEM_TLB_L1 0x08 /* L1 */
949#define PERF_MEM_TLB_L2 0x10 /* L2 */
950#define PERF_MEM_TLB_WK 0x20 /* Hardware Walker*/
951#define PERF_MEM_TLB_OS 0x40 /* OS fault handler */
952#define PERF_MEM_TLB_SHIFT 26
953
954#define PERF_MEM_S(a, s) \
955 (((__u64)PERF_MEM_##a##_##s) << PERF_MEM_##a##_SHIFT)
956
957/*
958 * single taken branch record layout:
959 *
960 * from: source instruction (may not always be a branch insn)
961 * to: branch target
962 * mispred: branch target was mispredicted
963 * predicted: branch target was predicted
964 *
965 * support for mispred, predicted is optional. In case it
966 * is not supported mispred = predicted = 0.
967 *
968 * in_tx: running in a hardware transaction
969 * abort: aborting a hardware transaction
970 * cycles: cycles from last branch (or 0 if not supported)
971 */
972struct perf_branch_entry {
973 __u64 from;
974 __u64 to;
975 __u64 mispred:1, /* target mispredicted */
976 predicted:1,/* target predicted */
977 in_tx:1, /* in transaction */
978 abort:1, /* transaction abort */
979 cycles:16, /* cycle count to last branch */
980 reserved:44;
981};
982
983#endif /* _UAPI_LINUX_PERF_EVENT_H */
diff --git a/tools/lib/api/Build b/tools/lib/api/Build
index 954c644f7ad9..6e2373db5598 100644
--- a/tools/lib/api/Build
+++ b/tools/lib/api/Build
@@ -2,3 +2,8 @@ libapi-y += fd/
2libapi-y += fs/ 2libapi-y += fs/
3libapi-y += cpu.o 3libapi-y += cpu.o
4libapi-y += debug.o 4libapi-y += debug.o
5libapi-y += str_error_r.o
6
7$(OUTPUT)str_error_r.o: ../str_error_r.c FORCE
8 $(call rule_mkdir)
9 $(call if_changed_dep,cc_o_c)
diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile
index 316f308a63ea..0a6fda9837f7 100644
--- a/tools/lib/api/Makefile
+++ b/tools/lib/api/Makefile
@@ -10,15 +10,23 @@ endif
10 10
11CC = $(CROSS_COMPILE)gcc 11CC = $(CROSS_COMPILE)gcc
12AR = $(CROSS_COMPILE)ar 12AR = $(CROSS_COMPILE)ar
13LD = $(CROSS_COMPILE)ld
13 14
14MAKEFLAGS += --no-print-directory 15MAKEFLAGS += --no-print-directory
15 16
16LIBFILE = $(OUTPUT)libapi.a 17LIBFILE = $(OUTPUT)libapi.a
17 18
18CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) 19CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
19CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC 20CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
21
22# Treat warnings as errors unless directed not to
23ifneq ($(WERROR),0)
24 CFLAGS += -Werror
25endif
26
20CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 27CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
21CFLAGS += -I$(srctree)/tools/lib/api 28CFLAGS += -I$(srctree)/tools/lib/api
29CFLAGS += -I$(srctree)/tools/include
22 30
23RM = rm -f 31RM = rm -f
24 32
diff --git a/tools/lib/api/fd/array.c b/tools/lib/api/fd/array.c
index 0e636c4339b8..b0a035fc87b3 100644
--- a/tools/lib/api/fd/array.c
+++ b/tools/lib/api/fd/array.c
@@ -85,7 +85,8 @@ int fdarray__add(struct fdarray *fda, int fd, short revents)
85} 85}
86 86
87int fdarray__filter(struct fdarray *fda, short revents, 87int fdarray__filter(struct fdarray *fda, short revents,
88 void (*entry_destructor)(struct fdarray *fda, int fd)) 88 void (*entry_destructor)(struct fdarray *fda, int fd, void *arg),
89 void *arg)
89{ 90{
90 int fd, nr = 0; 91 int fd, nr = 0;
91 92
@@ -95,7 +96,7 @@ int fdarray__filter(struct fdarray *fda, short revents,
95 for (fd = 0; fd < fda->nr; ++fd) { 96 for (fd = 0; fd < fda->nr; ++fd) {
96 if (fda->entries[fd].revents & revents) { 97 if (fda->entries[fd].revents & revents) {
97 if (entry_destructor) 98 if (entry_destructor)
98 entry_destructor(fda, fd); 99 entry_destructor(fda, fd, arg);
99 100
100 continue; 101 continue;
101 } 102 }
diff --git a/tools/lib/api/fd/array.h b/tools/lib/api/fd/array.h
index 45db01818f45..71287dddc05f 100644
--- a/tools/lib/api/fd/array.h
+++ b/tools/lib/api/fd/array.h
@@ -22,6 +22,7 @@ struct fdarray {
22 struct pollfd *entries; 22 struct pollfd *entries;
23 union { 23 union {
24 int idx; 24 int idx;
25 void *ptr;
25 } *priv; 26 } *priv;
26}; 27};
27 28
@@ -34,7 +35,8 @@ void fdarray__delete(struct fdarray *fda);
34int fdarray__add(struct fdarray *fda, int fd, short revents); 35int fdarray__add(struct fdarray *fda, int fd, short revents);
35int fdarray__poll(struct fdarray *fda, int timeout); 36int fdarray__poll(struct fdarray *fda, int timeout);
36int fdarray__filter(struct fdarray *fda, short revents, 37int fdarray__filter(struct fdarray *fda, short revents,
37 void (*entry_destructor)(struct fdarray *fda, int fd)); 38 void (*entry_destructor)(struct fdarray *fda, int fd, void *arg),
39 void *arg);
38int fdarray__grow(struct fdarray *fda, int extra); 40int fdarray__grow(struct fdarray *fda, int extra);
39int fdarray__fprintf(struct fdarray *fda, FILE *fp); 41int fdarray__fprintf(struct fdarray *fda, FILE *fp);
40 42
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index 08556cf2c70d..ba7094b945ff 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -283,6 +283,11 @@ int filename__read_int(const char *filename, int *value)
283 return err; 283 return err;
284} 284}
285 285
286/*
287 * Parses @value out of @filename with strtoull.
288 * By using 0 for base, the strtoull detects the
289 * base automatically (see man strtoull).
290 */
286int filename__read_ull(const char *filename, unsigned long long *value) 291int filename__read_ull(const char *filename, unsigned long long *value)
287{ 292{
288 char line[64]; 293 char line[64];
@@ -292,7 +297,7 @@ int filename__read_ull(const char *filename, unsigned long long *value)
292 return -1; 297 return -1;
293 298
294 if (read(fd, line, sizeof(line)) > 0) { 299 if (read(fd, line, sizeof(line)) > 0) {
295 *value = strtoull(line, NULL, 10); 300 *value = strtoull(line, NULL, 0);
296 if (*value != ULLONG_MAX) 301 if (*value != ULLONG_MAX)
297 err = 0; 302 err = 0;
298 } 303 }
diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c
index a26bb5ea8283..251b7c342a87 100644
--- a/tools/lib/api/fs/tracing_path.c
+++ b/tools/lib/api/fs/tracing_path.c
@@ -5,6 +5,7 @@
5#include <stdio.h> 5#include <stdio.h>
6#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h> 7#include <string.h>
8#include <linux/string.h>
8#include <errno.h> 9#include <errno.h>
9#include <unistd.h> 10#include <unistd.h>
10#include "fs.h" 11#include "fs.h"
@@ -118,7 +119,7 @@ static int strerror_open(int err, char *buf, size_t size, const char *filename)
118 } 119 }
119 break; 120 break;
120 default: 121 default:
121 snprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf))); 122 snprintf(buf, size, "%s", str_error_r(err, sbuf, sizeof(sbuf)));
122 break; 123 break;
123 } 124 }
124 125
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index fc1bc75ae56d..62d89d50fcbd 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -68,7 +68,7 @@ FEATURE_USER = .libbpf
68FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf 68FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf
69FEATURE_DISPLAY = libelf bpf 69FEATURE_DISPLAY = libelf bpf
70 70
71INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/arch/$(ARCH)/include/uapi -I$(srctree)/include/uapi 71INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi
72FEATURE_CHECK_CFLAGS-bpf = $(INCLUDES) 72FEATURE_CHECK_CFLAGS-bpf = $(INCLUDES)
73 73
74check_feat := 1 74check_feat := 1
@@ -154,6 +154,12 @@ all: fixdep $(VERSION_FILES) all_cmd
154all_cmd: $(CMD_TARGETS) 154all_cmd: $(CMD_TARGETS)
155 155
156$(BPF_IN): force elfdep bpfdep 156$(BPF_IN): force elfdep bpfdep
157 @(test -f ../../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \
158 (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \
159 echo "Warning: tools/include/uapi/linux/bpf.h differs from kernel" >&2 )) || true
160 @(test -f ../../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \
161 (diff -B ../../include/uapi/linux/bpf_common.h ../../../include/uapi/linux/bpf_common.h >/dev/null) || \
162 echo "Warning: tools/include/uapi/linux/bpf_common.h differs from kernel" >&2 )) || true
157 $(Q)$(MAKE) $(build)=libbpf 163 $(Q)$(MAKE) $(build)=libbpf
158 164
159$(OUTPUT)libbpf.so: $(BPF_IN) 165$(OUTPUT)libbpf.so: $(BPF_IN)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 1f91cc941b7c..4212ed62235b 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -4,6 +4,19 @@
4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> 4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> 5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
6 * Copyright (C) 2015 Huawei Inc. 6 * Copyright (C) 2015 Huawei Inc.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation;
11 * version 2.1 of the License (not later!)
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, see <http://www.gnu.org/licenses>
7 */ 20 */
8 21
9#include <stdlib.h> 22#include <stdlib.h>
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index a76465541292..e8ba54087497 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -4,6 +4,19 @@
4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> 4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> 5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
6 * Copyright (C) 2015 Huawei Inc. 6 * Copyright (C) 2015 Huawei Inc.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation;
11 * version 2.1 of the License (not later!)
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, see <http://www.gnu.org/licenses>
7 */ 20 */
8#ifndef __BPF_BPF_H 21#ifndef __BPF_BPF_H
9#define __BPF_BPF_H 22#define __BPF_BPF_H
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 7e543c3102d4..b699aea9a025 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -4,6 +4,19 @@
4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> 4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> 5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
6 * Copyright (C) 2015 Huawei Inc. 6 * Copyright (C) 2015 Huawei Inc.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation;
11 * version 2.1 of the License (not later!)
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, see <http://www.gnu.org/licenses>
7 */ 20 */
8 21
9#include <stdlib.h> 22#include <stdlib.h>
@@ -24,6 +37,10 @@
24#include "libbpf.h" 37#include "libbpf.h"
25#include "bpf.h" 38#include "bpf.h"
26 39
40#ifndef EM_BPF
41#define EM_BPF 247
42#endif
43
27#define __printf(a, b) __attribute__((format(printf, a, b))) 44#define __printf(a, b) __attribute__((format(printf, a, b)))
28 45
29__printf(1, 2) 46__printf(1, 2)
@@ -71,12 +88,13 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
71 [ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf", 88 [ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf",
72 [ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid", 89 [ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid",
73 [ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost", 90 [ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost",
74 [ERRCODE_OFFSET(ENDIAN)] = "Endian missmatch", 91 [ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch",
75 [ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf", 92 [ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf",
76 [ERRCODE_OFFSET(RELOC)] = "Relocation failed", 93 [ERRCODE_OFFSET(RELOC)] = "Relocation failed",
77 [ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading", 94 [ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading",
78 [ERRCODE_OFFSET(PROG2BIG)] = "Program too big", 95 [ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
79 [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version", 96 [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
97 [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
80}; 98};
81 99
82int libbpf_strerror(int err, char *buf, size_t size) 100int libbpf_strerror(int err, char *buf, size_t size)
@@ -145,6 +163,7 @@ struct bpf_program {
145 char *section_name; 163 char *section_name;
146 struct bpf_insn *insns; 164 struct bpf_insn *insns;
147 size_t insns_cnt; 165 size_t insns_cnt;
166 enum bpf_prog_type type;
148 167
149 struct { 168 struct {
150 int insn_idx; 169 int insn_idx;
@@ -286,6 +305,7 @@ bpf_program__init(void *data, size_t size, char *name, int idx,
286 prog->idx = idx; 305 prog->idx = idx;
287 prog->instances.fds = NULL; 306 prog->instances.fds = NULL;
288 prog->instances.nr = -1; 307 prog->instances.nr = -1;
308 prog->type = BPF_PROG_TYPE_KPROBE;
289 309
290 return 0; 310 return 0;
291errout: 311errout:
@@ -423,7 +443,8 @@ static int bpf_object__elf_init(struct bpf_object *obj)
423 } 443 }
424 ep = &obj->efile.ehdr; 444 ep = &obj->efile.ehdr;
425 445
426 if ((ep->e_type != ET_REL) || (ep->e_machine != 0)) { 446 /* Old LLVM set e_machine to EM_NONE */
447 if ((ep->e_type != ET_REL) || (ep->e_machine && (ep->e_machine != EM_BPF))) {
427 pr_warning("%s is not an eBPF object file\n", 448 pr_warning("%s is not an eBPF object file\n",
428 obj->path); 449 obj->path);
429 err = -LIBBPF_ERRNO__FORMAT; 450 err = -LIBBPF_ERRNO__FORMAT;
@@ -881,8 +902,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
881} 902}
882 903
883static int 904static int
884load_program(struct bpf_insn *insns, int insns_cnt, 905load_program(enum bpf_prog_type type, struct bpf_insn *insns,
885 char *license, u32 kern_version, int *pfd) 906 int insns_cnt, char *license, u32 kern_version, int *pfd)
886{ 907{
887 int ret; 908 int ret;
888 char *log_buf; 909 char *log_buf;
@@ -894,9 +915,8 @@ load_program(struct bpf_insn *insns, int insns_cnt,
894 if (!log_buf) 915 if (!log_buf)
895 pr_warning("Alloc log buffer for bpf loader error, continue without log\n"); 916 pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
896 917
897 ret = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns, 918 ret = bpf_load_program(type, insns, insns_cnt, license,
898 insns_cnt, license, kern_version, 919 kern_version, log_buf, BPF_LOG_BUF_SIZE);
899 log_buf, BPF_LOG_BUF_SIZE);
900 920
901 if (ret >= 0) { 921 if (ret >= 0) {
902 *pfd = ret; 922 *pfd = ret;
@@ -912,15 +932,27 @@ load_program(struct bpf_insn *insns, int insns_cnt,
912 pr_warning("-- BEGIN DUMP LOG ---\n"); 932 pr_warning("-- BEGIN DUMP LOG ---\n");
913 pr_warning("\n%s\n", log_buf); 933 pr_warning("\n%s\n", log_buf);
914 pr_warning("-- END LOG --\n"); 934 pr_warning("-- END LOG --\n");
935 } else if (insns_cnt >= BPF_MAXINSNS) {
936 pr_warning("Program too large (%d insns), at most %d insns\n",
937 insns_cnt, BPF_MAXINSNS);
938 ret = -LIBBPF_ERRNO__PROG2BIG;
915 } else { 939 } else {
916 if (insns_cnt >= BPF_MAXINSNS) { 940 /* Wrong program type? */
917 pr_warning("Program too large (%d insns), at most %d insns\n", 941 if (type != BPF_PROG_TYPE_KPROBE) {
918 insns_cnt, BPF_MAXINSNS); 942 int fd;
919 ret = -LIBBPF_ERRNO__PROG2BIG; 943
920 } else if (log_buf) { 944 fd = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
921 pr_warning("log buffer is empty\n"); 945 insns_cnt, license, kern_version,
922 ret = -LIBBPF_ERRNO__KVER; 946 NULL, 0);
947 if (fd >= 0) {
948 close(fd);
949 ret = -LIBBPF_ERRNO__PROGTYPE;
950 goto out;
951 }
923 } 952 }
953
954 if (log_buf)
955 ret = -LIBBPF_ERRNO__KVER;
924 } 956 }
925 957
926out: 958out:
@@ -955,7 +987,7 @@ bpf_program__load(struct bpf_program *prog,
955 pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n", 987 pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
956 prog->section_name, prog->instances.nr); 988 prog->section_name, prog->instances.nr);
957 } 989 }
958 err = load_program(prog->insns, prog->insns_cnt, 990 err = load_program(prog->type, prog->insns, prog->insns_cnt,
959 license, kern_version, &fd); 991 license, kern_version, &fd);
960 if (!err) 992 if (!err)
961 prog->instances.fds[0] = fd; 993 prog->instances.fds[0] = fd;
@@ -984,7 +1016,7 @@ bpf_program__load(struct bpf_program *prog,
984 continue; 1016 continue;
985 } 1017 }
986 1018
987 err = load_program(result.new_insn_ptr, 1019 err = load_program(prog->type, result.new_insn_ptr,
988 result.new_insn_cnt, 1020 result.new_insn_cnt,
989 license, kern_version, &fd); 1021 license, kern_version, &fd);
990 1022
@@ -1186,20 +1218,14 @@ bpf_object__next(struct bpf_object *prev)
1186 return next; 1218 return next;
1187} 1219}
1188 1220
1189const char * 1221const char *bpf_object__name(struct bpf_object *obj)
1190bpf_object__get_name(struct bpf_object *obj)
1191{ 1222{
1192 if (!obj) 1223 return obj ? obj->path : ERR_PTR(-EINVAL);
1193 return ERR_PTR(-EINVAL);
1194 return obj->path;
1195} 1224}
1196 1225
1197unsigned int 1226unsigned int bpf_object__kversion(struct bpf_object *obj)
1198bpf_object__get_kversion(struct bpf_object *obj)
1199{ 1227{
1200 if (!obj) 1228 return obj ? obj->kern_version : 0;
1201 return 0;
1202 return obj->kern_version;
1203} 1229}
1204 1230
1205struct bpf_program * 1231struct bpf_program *
@@ -1224,9 +1250,8 @@ bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
1224 return &obj->programs[idx]; 1250 return &obj->programs[idx];
1225} 1251}
1226 1252
1227int bpf_program__set_private(struct bpf_program *prog, 1253int bpf_program__set_priv(struct bpf_program *prog, void *priv,
1228 void *priv, 1254 bpf_program_clear_priv_t clear_priv)
1229 bpf_program_clear_priv_t clear_priv)
1230{ 1255{
1231 if (prog->priv && prog->clear_priv) 1256 if (prog->priv && prog->clear_priv)
1232 prog->clear_priv(prog, prog->priv); 1257 prog->clear_priv(prog, prog->priv);
@@ -1236,10 +1261,9 @@ int bpf_program__set_private(struct bpf_program *prog,
1236 return 0; 1261 return 0;
1237} 1262}
1238 1263
1239int bpf_program__get_private(struct bpf_program *prog, void **ppriv) 1264void *bpf_program__priv(struct bpf_program *prog)
1240{ 1265{
1241 *ppriv = prog->priv; 1266 return prog ? prog->priv : ERR_PTR(-EINVAL);
1242 return 0;
1243} 1267}
1244 1268
1245const char *bpf_program__title(struct bpf_program *prog, bool needs_copy) 1269const char *bpf_program__title(struct bpf_program *prog, bool needs_copy)
@@ -1311,32 +1335,61 @@ int bpf_program__nth_fd(struct bpf_program *prog, int n)
1311 return fd; 1335 return fd;
1312} 1336}
1313 1337
1314int bpf_map__get_fd(struct bpf_map *map) 1338static void bpf_program__set_type(struct bpf_program *prog,
1339 enum bpf_prog_type type)
1315{ 1340{
1316 if (!map) 1341 prog->type = type;
1317 return -EINVAL;
1318
1319 return map->fd;
1320} 1342}
1321 1343
1322int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef) 1344int bpf_program__set_tracepoint(struct bpf_program *prog)
1323{ 1345{
1324 if (!map || !pdef) 1346 if (!prog)
1325 return -EINVAL; 1347 return -EINVAL;
1348 bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
1349 return 0;
1350}
1326 1351
1327 *pdef = map->def; 1352int bpf_program__set_kprobe(struct bpf_program *prog)
1353{
1354 if (!prog)
1355 return -EINVAL;
1356 bpf_program__set_type(prog, BPF_PROG_TYPE_KPROBE);
1328 return 0; 1357 return 0;
1329} 1358}
1330 1359
1331const char *bpf_map__get_name(struct bpf_map *map) 1360static bool bpf_program__is_type(struct bpf_program *prog,
1361 enum bpf_prog_type type)
1332{ 1362{
1333 if (!map) 1363 return prog ? (prog->type == type) : false;
1334 return NULL; 1364}
1335 return map->name; 1365
1366bool bpf_program__is_tracepoint(struct bpf_program *prog)
1367{
1368 return bpf_program__is_type(prog, BPF_PROG_TYPE_TRACEPOINT);
1369}
1370
1371bool bpf_program__is_kprobe(struct bpf_program *prog)
1372{
1373 return bpf_program__is_type(prog, BPF_PROG_TYPE_KPROBE);
1374}
1375
1376int bpf_map__fd(struct bpf_map *map)
1377{
1378 return map ? map->fd : -EINVAL;
1336} 1379}
1337 1380
1338int bpf_map__set_private(struct bpf_map *map, void *priv, 1381const struct bpf_map_def *bpf_map__def(struct bpf_map *map)
1339 bpf_map_clear_priv_t clear_priv) 1382{
1383 return map ? &map->def : ERR_PTR(-EINVAL);
1384}
1385
1386const char *bpf_map__name(struct bpf_map *map)
1387{
1388 return map ? map->name : NULL;
1389}
1390
1391int bpf_map__set_priv(struct bpf_map *map, void *priv,
1392 bpf_map_clear_priv_t clear_priv)
1340{ 1393{
1341 if (!map) 1394 if (!map)
1342 return -EINVAL; 1395 return -EINVAL;
@@ -1351,14 +1404,9 @@ int bpf_map__set_private(struct bpf_map *map, void *priv,
1351 return 0; 1404 return 0;
1352} 1405}
1353 1406
1354int bpf_map__get_private(struct bpf_map *map, void **ppriv) 1407void *bpf_map__priv(struct bpf_map *map)
1355{ 1408{
1356 if (!map) 1409 return map ? map->priv : ERR_PTR(-EINVAL);
1357 return -EINVAL;
1358
1359 if (ppriv)
1360 *ppriv = map->priv;
1361 return 0;
1362} 1410}
1363 1411
1364struct bpf_map * 1412struct bpf_map *
@@ -1389,7 +1437,7 @@ bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
1389} 1437}
1390 1438
1391struct bpf_map * 1439struct bpf_map *
1392bpf_object__get_map_by_name(struct bpf_object *obj, const char *name) 1440bpf_object__find_map_by_name(struct bpf_object *obj, const char *name)
1393{ 1441{
1394 struct bpf_map *pos; 1442 struct bpf_map *pos;
1395 1443
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index a51594c7b518..dd7a513efb10 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -4,6 +4,19 @@
4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> 4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> 5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
6 * Copyright (C) 2015 Huawei Inc. 6 * Copyright (C) 2015 Huawei Inc.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation;
11 * version 2.1 of the License (not later!)
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, see <http://www.gnu.org/licenses>
7 */ 20 */
8#ifndef __BPF_LIBBPF_H 21#ifndef __BPF_LIBBPF_H
9#define __BPF_LIBBPF_H 22#define __BPF_LIBBPF_H
@@ -19,13 +32,14 @@ enum libbpf_errno {
19 LIBBPF_ERRNO__LIBELF = __LIBBPF_ERRNO__START, 32 LIBBPF_ERRNO__LIBELF = __LIBBPF_ERRNO__START,
20 LIBBPF_ERRNO__FORMAT, /* BPF object format invalid */ 33 LIBBPF_ERRNO__FORMAT, /* BPF object format invalid */
21 LIBBPF_ERRNO__KVERSION, /* Incorrect or no 'version' section */ 34 LIBBPF_ERRNO__KVERSION, /* Incorrect or no 'version' section */
22 LIBBPF_ERRNO__ENDIAN, /* Endian missmatch */ 35 LIBBPF_ERRNO__ENDIAN, /* Endian mismatch */
23 LIBBPF_ERRNO__INTERNAL, /* Internal error in libbpf */ 36 LIBBPF_ERRNO__INTERNAL, /* Internal error in libbpf */
24 LIBBPF_ERRNO__RELOC, /* Relocation failed */ 37 LIBBPF_ERRNO__RELOC, /* Relocation failed */
25 LIBBPF_ERRNO__LOAD, /* Load program failure for unknown reason */ 38 LIBBPF_ERRNO__LOAD, /* Load program failure for unknown reason */
26 LIBBPF_ERRNO__VERIFY, /* Kernel verifier blocks program loading */ 39 LIBBPF_ERRNO__VERIFY, /* Kernel verifier blocks program loading */
27 LIBBPF_ERRNO__PROG2BIG, /* Program too big */ 40 LIBBPF_ERRNO__PROG2BIG, /* Program too big */
28 LIBBPF_ERRNO__KVER, /* Incorrect kernel version */ 41 LIBBPF_ERRNO__KVER, /* Incorrect kernel version */
42 LIBBPF_ERRNO__PROGTYPE, /* Kernel doesn't support this program type */
29 __LIBBPF_ERRNO__END, 43 __LIBBPF_ERRNO__END,
30}; 44};
31 45
@@ -55,8 +69,8 @@ void bpf_object__close(struct bpf_object *object);
55/* Load/unload object into/from kernel */ 69/* Load/unload object into/from kernel */
56int bpf_object__load(struct bpf_object *obj); 70int bpf_object__load(struct bpf_object *obj);
57int bpf_object__unload(struct bpf_object *obj); 71int bpf_object__unload(struct bpf_object *obj);
58const char *bpf_object__get_name(struct bpf_object *obj); 72const char *bpf_object__name(struct bpf_object *obj);
59unsigned int bpf_object__get_kversion(struct bpf_object *obj); 73unsigned int bpf_object__kversion(struct bpf_object *obj);
60 74
61struct bpf_object *bpf_object__next(struct bpf_object *prev); 75struct bpf_object *bpf_object__next(struct bpf_object *prev);
62#define bpf_object__for_each_safe(pos, tmp) \ 76#define bpf_object__for_each_safe(pos, tmp) \
@@ -78,11 +92,10 @@ struct bpf_program *bpf_program__next(struct bpf_program *prog,
78typedef void (*bpf_program_clear_priv_t)(struct bpf_program *, 92typedef void (*bpf_program_clear_priv_t)(struct bpf_program *,
79 void *); 93 void *);
80 94
81int bpf_program__set_private(struct bpf_program *prog, void *priv, 95int bpf_program__set_priv(struct bpf_program *prog, void *priv,
82 bpf_program_clear_priv_t clear_priv); 96 bpf_program_clear_priv_t clear_priv);
83 97
84int bpf_program__get_private(struct bpf_program *prog, 98void *bpf_program__priv(struct bpf_program *prog);
85 void **ppriv);
86 99
87const char *bpf_program__title(struct bpf_program *prog, bool needs_copy); 100const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
88 101
@@ -153,6 +166,15 @@ int bpf_program__set_prep(struct bpf_program *prog, int nr_instance,
153int bpf_program__nth_fd(struct bpf_program *prog, int n); 166int bpf_program__nth_fd(struct bpf_program *prog, int n);
154 167
155/* 168/*
169 * Adjust type of bpf program. Default is kprobe.
170 */
171int bpf_program__set_tracepoint(struct bpf_program *prog);
172int bpf_program__set_kprobe(struct bpf_program *prog);
173
174bool bpf_program__is_tracepoint(struct bpf_program *prog);
175bool bpf_program__is_kprobe(struct bpf_program *prog);
176
177/*
156 * We don't need __attribute__((packed)) now since it is 178 * We don't need __attribute__((packed)) now since it is
157 * unnecessary for 'bpf_map_def' because they are all aligned. 179 * unnecessary for 'bpf_map_def' because they are all aligned.
158 * In addition, using it will trigger -Wpacked warning message, 180 * In addition, using it will trigger -Wpacked warning message,
@@ -171,7 +193,7 @@ struct bpf_map_def {
171 */ 193 */
172struct bpf_map; 194struct bpf_map;
173struct bpf_map * 195struct bpf_map *
174bpf_object__get_map_by_name(struct bpf_object *obj, const char *name); 196bpf_object__find_map_by_name(struct bpf_object *obj, const char *name);
175 197
176struct bpf_map * 198struct bpf_map *
177bpf_map__next(struct bpf_map *map, struct bpf_object *obj); 199bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
@@ -180,13 +202,13 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
180 (pos) != NULL; \ 202 (pos) != NULL; \
181 (pos) = bpf_map__next((pos), (obj))) 203 (pos) = bpf_map__next((pos), (obj)))
182 204
183int bpf_map__get_fd(struct bpf_map *map); 205int bpf_map__fd(struct bpf_map *map);
184int bpf_map__get_def(struct bpf_map *map, struct bpf_map_def *pdef); 206const struct bpf_map_def *bpf_map__def(struct bpf_map *map);
185const char *bpf_map__get_name(struct bpf_map *map); 207const char *bpf_map__name(struct bpf_map *map);
186 208
187typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); 209typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
188int bpf_map__set_private(struct bpf_map *map, void *priv, 210int bpf_map__set_priv(struct bpf_map *map, void *priv,
189 bpf_map_clear_priv_t clear_priv); 211 bpf_map_clear_priv_t clear_priv);
190int bpf_map__get_private(struct bpf_map *map, void **ppriv); 212void *bpf_map__priv(struct bpf_map *map);
191 213
192#endif 214#endif
diff --git a/tools/lib/str_error_r.c b/tools/lib/str_error_r.c
new file mode 100644
index 000000000000..503ae072244c
--- /dev/null
+++ b/tools/lib/str_error_r.c
@@ -0,0 +1,26 @@
1#undef _GNU_SOURCE
2#include <string.h>
3#include <stdio.h>
4#include <linux/string.h>
5
6/*
7 * The tools so far have been using the strerror_r() GNU variant, that returns
8 * a string, be it the buffer passed or something else.
9 *
10 * But that, besides being tricky in cases where we expect that the function
11 * using strerror_r() returns the error formatted in a provided buffer (we have
12 * to check if it returned something else and copy that instead), breaks the
13 * build on systems not using glibc, like Alpine Linux, where musl libc is
14 * used.
15 *
16 * So, introduce yet another wrapper, str_error_r(), that has the GNU
17 * interface, but uses the portable XSI variant of strerror_r(), so that users
18 * rest asured that the provided buffer is used and it is what is returned.
19 */
20char *str_error_r(int errnum, char *buf, size_t buflen)
21{
22 int err = strerror_r(errnum, buf, buflen);
23 if (err)
24 snprintf(buf, buflen, "INTERNAL ERROR: strerror_r(%d, %p, %zd)=%d", errnum, buf, buflen, err);
25 return buf;
26}
diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile
index a8103700c172..ce4b7e527566 100644
--- a/tools/lib/subcmd/Makefile
+++ b/tools/lib/subcmd/Makefile
@@ -19,7 +19,13 @@ MAKEFLAGS += --no-print-directory
19LIBFILE = $(OUTPUT)libsubcmd.a 19LIBFILE = $(OUTPUT)libsubcmd.a
20 20
21CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) 21CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
22CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC 22CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
23
24# Treat warnings as errors unless directed not to
25ifneq ($(WERROR),0)
26 CFLAGS += -Werror
27endif
28
23CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE 29CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
24 30
25CFLAGS += -I$(srctree)/tools/include/ 31CFLAGS += -I$(srctree)/tools/include/
diff --git a/tools/lib/subcmd/run-command.c b/tools/lib/subcmd/run-command.c
index f4f6c9eb8e59..911f83942723 100644
--- a/tools/lib/subcmd/run-command.c
+++ b/tools/lib/subcmd/run-command.c
@@ -3,6 +3,7 @@
3#include <sys/stat.h> 3#include <sys/stat.h>
4#include <fcntl.h> 4#include <fcntl.h>
5#include <string.h> 5#include <string.h>
6#include <linux/string.h>
6#include <errno.h> 7#include <errno.h>
7#include <sys/wait.h> 8#include <sys/wait.h>
8#include "subcmd-util.h" 9#include "subcmd-util.h"
@@ -109,7 +110,7 @@ int start_command(struct child_process *cmd)
109 110
110 if (cmd->dir && chdir(cmd->dir)) 111 if (cmd->dir && chdir(cmd->dir))
111 die("exec %s: cd to %s failed (%s)", cmd->argv[0], 112 die("exec %s: cd to %s failed (%s)", cmd->argv[0],
112 cmd->dir, strerror_r(errno, sbuf, sizeof(sbuf))); 113 cmd->dir, str_error_r(errno, sbuf, sizeof(sbuf)));
113 if (cmd->env) { 114 if (cmd->env) {
114 for (; *cmd->env; cmd->env++) { 115 for (; *cmd->env; cmd->env++) {
115 if (strchr(*cmd->env, '=')) 116 if (strchr(*cmd->env, '='))
@@ -173,7 +174,7 @@ static int wait_or_whine(pid_t pid)
173 if (errno == EINTR) 174 if (errno == EINTR)
174 continue; 175 continue;
175 fprintf(stderr, " Error: waitpid failed (%s)", 176 fprintf(stderr, " Error: waitpid failed (%s)",
176 strerror_r(errno, sbuf, sizeof(sbuf))); 177 str_error_r(errno, sbuf, sizeof(sbuf)));
177 return -ERR_RUN_COMMAND_WAITPID; 178 return -ERR_RUN_COMMAND_WAITPID;
178 } 179 }
179 if (waiting != pid) 180 if (waiting != pid)
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index a8b6357d1ffe..664c90c8e22b 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -23,6 +23,7 @@
23 * Frederic Weisbecker gave his permission to relicense the code to 23 * Frederic Weisbecker gave his permission to relicense the code to
24 * the Lesser General Public License. 24 * the Lesser General Public License.
25 */ 25 */
26#include <inttypes.h>
26#include <stdio.h> 27#include <stdio.h>
27#include <stdlib.h> 28#include <stdlib.h>
28#include <string.h> 29#include <string.h>
@@ -31,8 +32,9 @@
31#include <errno.h> 32#include <errno.h>
32#include <stdint.h> 33#include <stdint.h>
33#include <limits.h> 34#include <limits.h>
35#include <linux/string.h>
34 36
35#include <netinet/ip6.h> 37#include <netinet/in.h>
36#include "event-parse.h" 38#include "event-parse.h"
37#include "event-utils.h" 39#include "event-utils.h"
38 40
@@ -6131,12 +6133,7 @@ int pevent_strerror(struct pevent *pevent __maybe_unused,
6131 const char *msg; 6133 const char *msg;
6132 6134
6133 if (errnum >= 0) { 6135 if (errnum >= 0) {
6134 msg = strerror_r(errnum, buf, buflen); 6136 str_error_r(errnum, buf, buflen);
6135 if (msg != buf) {
6136 size_t len = strlen(msg);
6137 memcpy(buf, msg, min(buflen - 1, len));
6138 *(buf + min(buflen - 1, len)) = '\0';
6139 }
6140 return 0; 6137 return 0;
6141 } 6138 }
6142 6139
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 88cccea3ca99..7c214ceb9386 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -28,11 +28,16 @@
28#include "event-utils.h" 28#include "event-utils.h"
29 29
30#define COMM "COMM" 30#define COMM "COMM"
31#define CPU "CPU"
31 32
32static struct format_field comm = { 33static struct format_field comm = {
33 .name = "COMM", 34 .name = "COMM",
34}; 35};
35 36
37static struct format_field cpu = {
38 .name = "CPU",
39};
40
36struct event_list { 41struct event_list {
37 struct event_list *next; 42 struct event_list *next;
38 struct event_format *event; 43 struct event_format *event;
@@ -382,14 +387,17 @@ create_arg_item(struct event_format *event, const char *token,
382 /* Consider this a field */ 387 /* Consider this a field */
383 field = pevent_find_any_field(event, token); 388 field = pevent_find_any_field(event, token);
384 if (!field) { 389 if (!field) {
385 if (strcmp(token, COMM) != 0) { 390 /* If token is 'COMM' or 'CPU' then it is special */
391 if (strcmp(token, COMM) == 0) {
392 field = &comm;
393 } else if (strcmp(token, CPU) == 0) {
394 field = &cpu;
395 } else {
386 /* not a field, Make it false */ 396 /* not a field, Make it false */
387 arg->type = FILTER_ARG_BOOLEAN; 397 arg->type = FILTER_ARG_BOOLEAN;
388 arg->boolean.value = FILTER_FALSE; 398 arg->boolean.value = FILTER_FALSE;
389 break; 399 break;
390 } 400 }
391 /* If token is 'COMM' then it is special */
392 field = &comm;
393 } 401 }
394 arg->type = FILTER_ARG_FIELD; 402 arg->type = FILTER_ARG_FIELD;
395 arg->field.field = field; 403 arg->field.field = field;
@@ -1718,6 +1726,10 @@ get_value(struct event_format *event,
1718 return (unsigned long)name; 1726 return (unsigned long)name;
1719 } 1727 }
1720 1728
1729 /* Handle our dummy "cpu" field */
1730 if (field == &cpu)
1731 return record->cpu;
1732
1721 pevent_read_number_field(field, record->data, &val); 1733 pevent_read_number_field(field, record->data, &val);
1722 1734
1723 if (!(field->flags & FIELD_IS_SIGNED)) 1735 if (!(field->flags & FIELD_IS_SIGNED))
diff --git a/tools/lib/vsprintf.c b/tools/lib/vsprintf.c
new file mode 100644
index 000000000000..45f9a06daa56
--- /dev/null
+++ b/tools/lib/vsprintf.c
@@ -0,0 +1,24 @@
1#include <sys/types.h>
2#include <linux/kernel.h>
3#include <stdio.h>
4
5int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
6{
7 int i = vsnprintf(buf, size, fmt, args);
8 ssize_t ssize = size;
9
10 return (i >= ssize) ? (ssize - 1) : i;
11}
12
13int scnprintf(char * buf, size_t size, const char * fmt, ...)
14{
15 ssize_t ssize = size;
16 va_list args;
17 int i;
18
19 va_start(args, fmt);
20 i = vsnprintf(buf, size, fmt, args);
21 va_end(args);
22
23 return (i >= ssize) ? (ssize - 1) : i;
24}
diff --git a/tools/objtool/.gitignore b/tools/objtool/.gitignore
index a0b3128bb31f..d3102c865a95 100644
--- a/tools/objtool/.gitignore
+++ b/tools/objtool/.gitignore
@@ -1,2 +1,3 @@
1arch/x86/insn/inat-tables.c 1arch/x86/insn/inat-tables.c
2objtool 2objtool
3fixdep
diff --git a/tools/objtool/Build b/tools/objtool/Build
index 0e89258a3541..d6cdece5e58b 100644
--- a/tools/objtool/Build
+++ b/tools/objtool/Build
@@ -1,13 +1,18 @@
1objtool-y += arch/$(ARCH)/ 1objtool-y += arch/$(SRCARCH)/
2objtool-y += builtin-check.o 2objtool-y += builtin-check.o
3objtool-y += elf.o 3objtool-y += elf.o
4objtool-y += special.o 4objtool-y += special.o
5objtool-y += objtool.o 5objtool-y += objtool.o
6 6
7objtool-y += libstring.o 7objtool-y += libstring.o
8objtool-y += str_error_r.o
8 9
9CFLAGS += -I$(srctree)/tools/lib 10CFLAGS += -I$(srctree)/tools/lib
10 11
11$(OUTPUT)libstring.o: ../lib/string.c FORCE 12$(OUTPUT)libstring.o: ../lib/string.c FORCE
12 $(call rule_mkdir) 13 $(call rule_mkdir)
13 $(call if_changed_dep,cc_o_c) 14 $(call if_changed_dep,cc_o_c)
15
16$(OUTPUT)str_error_r.o: ../lib/str_error_r.c FORCE
17 $(call rule_mkdir)
18 $(call if_changed_dep,cc_o_c)
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index f094f3c4ed84..041b493ad3ab 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -1,11 +1,9 @@
1include ../scripts/Makefile.include 1include ../scripts/Makefile.include
2include ../scripts/Makefile.arch
2 3
3ifndef ($(ARCH))
4ARCH ?= $(shell uname -m)
5ifeq ($(ARCH),x86_64) 4ifeq ($(ARCH),x86_64)
6ARCH := x86 5ARCH := x86
7endif 6endif
8endif
9 7
10# always use the host compiler 8# always use the host compiler
11CC = gcc 9CC = gcc
@@ -26,7 +24,7 @@ OBJTOOL_IN := $(OBJTOOL)-in.o
26 24
27all: $(OBJTOOL) 25all: $(OBJTOOL)
28 26
29INCLUDES := -I$(srctree)/tools/include 27INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi
30CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) 28CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
31LDFLAGS += -lelf $(LIBSUBCMD) 29LDFLAGS += -lelf $(LIBSUBCMD)
32 30
@@ -35,14 +33,17 @@ elfshdr := $(shell echo '\#include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | gre
35CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED) 33CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED)
36 34
37AWK = awk 35AWK = awk
38export srctree OUTPUT CFLAGS ARCH AWK 36export srctree OUTPUT CFLAGS SRCARCH AWK
39include $(srctree)/tools/build/Makefile.include 37include $(srctree)/tools/build/Makefile.include
40 38
41$(OBJTOOL_IN): fixdep FORCE 39$(OBJTOOL_IN): fixdep FORCE
42 @$(MAKE) $(build)=objtool 40 @$(MAKE) $(build)=objtool
43 41
42# Busybox's diff doesn't have -I, avoid warning in that case
43#
44$(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN) 44$(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
45 @(test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \ 45 @(diff -I 2>&1 | grep -q 'option requires an argument' && \
46 test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \
46 diff -I'^#include' arch/x86/insn/insn.c ../../arch/x86/lib/insn.c >/dev/null && \ 47 diff -I'^#include' arch/x86/insn/insn.c ../../arch/x86/lib/insn.c >/dev/null && \
47 diff -I'^#include' arch/x86/insn/inat.c ../../arch/x86/lib/inat.c >/dev/null && \ 48 diff -I'^#include' arch/x86/insn/inat.c ../../arch/x86/lib/inat.c >/dev/null && \
48 diff arch/x86/insn/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \ 49 diff arch/x86/insn/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \
@@ -50,7 +51,7 @@ $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
50 diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \ 51 diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \
51 diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \ 52 diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \
52 diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \ 53 diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \
53 || echo "Warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true 54 || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true
54 $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@ 55 $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@
55 56
56 57
diff --git a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
index 093a892026f9..a3d2c62fd805 100644
--- a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
+++ b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
@@ -72,12 +72,14 @@ BEGIN {
72 lprefix_expr = "\\((66|F2|F3)\\)" 72 lprefix_expr = "\\((66|F2|F3)\\)"
73 max_lprefix = 4 73 max_lprefix = 4
74 74
75 # All opcodes starting with lower-case 'v' or with (v1) superscript 75 # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
76 # accepts VEX prefix 76 # accepts VEX prefix
77 vexok_opcode_expr = "^v.*" 77 vexok_opcode_expr = "^[vk].*"
78 vexok_expr = "\\(v1\\)" 78 vexok_expr = "\\(v1\\)"
79 # All opcodes with (v) superscript supports *only* VEX prefix 79 # All opcodes with (v) superscript supports *only* VEX prefix
80 vexonly_expr = "\\(v\\)" 80 vexonly_expr = "\\(v\\)"
81 # All opcodes with (ev) superscript supports *only* EVEX prefix
82 evexonly_expr = "\\(ev\\)"
81 83
82 prefix_expr = "\\(Prefix\\)" 84 prefix_expr = "\\(Prefix\\)"
83 prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" 85 prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -95,6 +97,7 @@ BEGIN {
95 prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" 97 prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
96 prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" 98 prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
97 prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" 99 prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
100 prefix_num["EVEX"] = "INAT_PFX_EVEX"
98 101
99 clear_vars() 102 clear_vars()
100} 103}
@@ -319,7 +322,9 @@ function convert_operands(count,opnd, i,j,imm,mod)
319 flags = add_flags(flags, "INAT_MODRM") 322 flags = add_flags(flags, "INAT_MODRM")
320 323
321 # check VEX codes 324 # check VEX codes
322 if (match(ext, vexonly_expr)) 325 if (match(ext, evexonly_expr))
326 flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
327 else if (match(ext, vexonly_expr))
323 flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") 328 flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
324 else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) 329 else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
325 flags = add_flags(flags, "INAT_VEXOK") 330 flags = add_flags(flags, "INAT_VEXOK")
diff --git a/tools/objtool/arch/x86/insn/inat.h b/tools/objtool/arch/x86/insn/inat.h
index 611645e903a8..125ecd2a300d 100644
--- a/tools/objtool/arch/x86/insn/inat.h
+++ b/tools/objtool/arch/x86/insn/inat.h
@@ -48,6 +48,7 @@
48/* AVX VEX prefixes */ 48/* AVX VEX prefixes */
49#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ 49#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
50#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ 50#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
51#define INAT_PFX_EVEX 15 /* EVEX prefix */
51 52
52#define INAT_LSTPFX_MAX 3 53#define INAT_LSTPFX_MAX 3
53#define INAT_LGCPFX_MAX 11 54#define INAT_LGCPFX_MAX 11
@@ -89,6 +90,7 @@
89#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) 90#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
90#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) 91#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
91#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) 92#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
93#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
92/* Attribute making macros for attribute tables */ 94/* Attribute making macros for attribute tables */
93#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) 95#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
94#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) 96#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
141static inline int inat_is_vex_prefix(insn_attr_t attr) 143static inline int inat_is_vex_prefix(insn_attr_t attr)
142{ 144{
143 attr &= INAT_PFX_MASK; 145 attr &= INAT_PFX_MASK;
144 return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3; 146 return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
147 attr == INAT_PFX_EVEX;
148}
149
150static inline int inat_is_evex_prefix(insn_attr_t attr)
151{
152 return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
145} 153}
146 154
147static inline int inat_is_vex3_prefix(insn_attr_t attr) 155static inline int inat_is_vex3_prefix(insn_attr_t attr)
@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_attr_t attr)
216 224
217static inline int inat_must_vex(insn_attr_t attr) 225static inline int inat_must_vex(insn_attr_t attr)
218{ 226{
219 return attr & INAT_VEXONLY; 227 return attr & (INAT_VEXONLY | INAT_EVEXONLY);
228}
229
230static inline int inat_must_evex(insn_attr_t attr)
231{
232 return attr & INAT_EVEXONLY;
220} 233}
221#endif 234#endif
diff --git a/tools/objtool/arch/x86/insn/insn.c b/tools/objtool/arch/x86/insn/insn.c
index 9f26eae6c9f0..ca983e2bea8b 100644
--- a/tools/objtool/arch/x86/insn/insn.c
+++ b/tools/objtool/arch/x86/insn/insn.c
@@ -155,14 +155,24 @@ found:
155 /* 155 /*
156 * In 32-bits mode, if the [7:6] bits (mod bits of 156 * In 32-bits mode, if the [7:6] bits (mod bits of
157 * ModRM) on the second byte are not 11b, it is 157 * ModRM) on the second byte are not 11b, it is
158 * LDS or LES. 158 * LDS or LES or BOUND.
159 */ 159 */
160 if (X86_MODRM_MOD(b2) != 3) 160 if (X86_MODRM_MOD(b2) != 3)
161 goto vex_end; 161 goto vex_end;
162 } 162 }
163 insn->vex_prefix.bytes[0] = b; 163 insn->vex_prefix.bytes[0] = b;
164 insn->vex_prefix.bytes[1] = b2; 164 insn->vex_prefix.bytes[1] = b2;
165 if (inat_is_vex3_prefix(attr)) { 165 if (inat_is_evex_prefix(attr)) {
166 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
167 insn->vex_prefix.bytes[2] = b2;
168 b2 = peek_nbyte_next(insn_byte_t, insn, 3);
169 insn->vex_prefix.bytes[3] = b2;
170 insn->vex_prefix.nbytes = 4;
171 insn->next_byte += 4;
172 if (insn->x86_64 && X86_VEX_W(b2))
173 /* VEX.W overrides opnd_size */
174 insn->opnd_bytes = 8;
175 } else if (inat_is_vex3_prefix(attr)) {
166 b2 = peek_nbyte_next(insn_byte_t, insn, 2); 176 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
167 insn->vex_prefix.bytes[2] = b2; 177 insn->vex_prefix.bytes[2] = b2;
168 insn->vex_prefix.nbytes = 3; 178 insn->vex_prefix.nbytes = 3;
@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
221 m = insn_vex_m_bits(insn); 231 m = insn_vex_m_bits(insn);
222 p = insn_vex_p_bits(insn); 232 p = insn_vex_p_bits(insn);
223 insn->attr = inat_get_avx_attribute(op, m, p); 233 insn->attr = inat_get_avx_attribute(op, m, p);
224 if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr)) 234 if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
235 (!inat_accept_vex(insn->attr) &&
236 !inat_is_group(insn->attr)))
225 insn->attr = 0; /* This instruction is bad */ 237 insn->attr = 0; /* This instruction is bad */
226 goto end; /* VEX has only 1 byte for opcode */ 238 goto end; /* VEX has only 1 byte for opcode */
227 } 239 }
diff --git a/tools/objtool/arch/x86/insn/insn.h b/tools/objtool/arch/x86/insn/insn.h
index dd12da0f4593..e23578c7b1be 100644
--- a/tools/objtool/arch/x86/insn/insn.h
+++ b/tools/objtool/arch/x86/insn/insn.h
@@ -91,6 +91,7 @@ struct insn {
91#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ 91#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
92#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ 92#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
93/* VEX bit fields */ 93/* VEX bit fields */
94#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
94#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ 95#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
95#define X86_VEX2_M 1 /* VEX2.M always 1 */ 96#define X86_VEX2_M 1 /* VEX2.M always 1 */
96#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ 97#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct insn *insn)
133 return (insn->vex_prefix.value != 0); 134 return (insn->vex_prefix.value != 0);
134} 135}
135 136
137static inline int insn_is_evex(struct insn *insn)
138{
139 if (!insn->prefixes.got)
140 insn_get_prefixes(insn);
141 return (insn->vex_prefix.nbytes == 4);
142}
143
136/* Ensure this instruction is decoded completely */ 144/* Ensure this instruction is decoded completely */
137static inline int insn_complete(struct insn *insn) 145static inline int insn_complete(struct insn *insn)
138{ 146{
@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
144{ 152{
145 if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ 153 if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
146 return X86_VEX2_M; 154 return X86_VEX2_M;
147 else 155 else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
148 return X86_VEX3_M(insn->vex_prefix.bytes[1]); 156 return X86_VEX3_M(insn->vex_prefix.bytes[1]);
157 else /* EVEX */
158 return X86_EVEX_M(insn->vex_prefix.bytes[1]);
149} 159}
150 160
151static inline insn_byte_t insn_vex_p_bits(struct insn *insn) 161static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
diff --git a/tools/objtool/arch/x86/insn/x86-opcode-map.txt b/tools/objtool/arch/x86/insn/x86-opcode-map.txt
index d388de72eaca..767be7c76034 100644
--- a/tools/objtool/arch/x86/insn/x86-opcode-map.txt
+++ b/tools/objtool/arch/x86/insn/x86-opcode-map.txt
@@ -13,12 +13,17 @@
13# opcode: escape # escaped-name 13# opcode: escape # escaped-name
14# EndTable 14# EndTable
15# 15#
16# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
17# mnemonics that begin with lowercase 'k' accept a VEX prefix
18#
16#<group maps> 19#<group maps>
17# GrpTable: GrpXXX 20# GrpTable: GrpXXX
18# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] 21# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
19# EndTable 22# EndTable
20# 23#
21# AVX Superscripts 24# AVX Superscripts
25# (ev): this opcode requires EVEX prefix.
26# (evo): this opcode is changed by EVEX prefix (EVEX opcode)
22# (v): this opcode requires VEX prefix. 27# (v): this opcode requires VEX prefix.
23# (v1): this opcode only supports 128bit VEX. 28# (v1): this opcode only supports 128bit VEX.
24# 29#
@@ -137,7 +142,7 @@ AVXcode:
137# 0x60 - 0x6f 142# 0x60 - 0x6f
13860: PUSHA/PUSHAD (i64) 14360: PUSHA/PUSHAD (i64)
13961: POPA/POPAD (i64) 14461: POPA/POPAD (i64)
14062: BOUND Gv,Ma (i64) 14562: BOUND Gv,Ma (i64) | EVEX (Prefix)
14163: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) 14663: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
14264: SEG=FS (Prefix) 14764: SEG=FS (Prefix)
14365: SEG=GS (Prefix) 14865: SEG=GS (Prefix)
@@ -399,17 +404,17 @@ AVXcode: 1
3993f: 4043f:
400# 0x0f 0x40-0x4f 405# 0x0f 0x40-0x4f
40140: CMOVO Gv,Ev 40640: CMOVO Gv,Ev
40241: CMOVNO Gv,Ev 40741: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
40342: CMOVB/C/NAE Gv,Ev 40842: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
40443: CMOVAE/NB/NC Gv,Ev 40943: CMOVAE/NB/NC Gv,Ev
40544: CMOVE/Z Gv,Ev 41044: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
40645: CMOVNE/NZ Gv,Ev 41145: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
40746: CMOVBE/NA Gv,Ev 41246: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
40847: CMOVA/NBE Gv,Ev 41347: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
40948: CMOVS Gv,Ev 41448: CMOVS Gv,Ev
41049: CMOVNS Gv,Ev 41549: CMOVNS Gv,Ev
4114a: CMOVP/PE Gv,Ev 4164a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
4124b: CMOVNP/PO Gv,Ev 4174b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
4134c: CMOVL/NGE Gv,Ev 4184c: CMOVL/NGE Gv,Ev
4144d: CMOVNL/GE Gv,Ev 4194d: CMOVNL/GE Gv,Ev
4154e: CMOVLE/NG Gv,Ev 4204e: CMOVLE/NG Gv,Ev
@@ -426,7 +431,7 @@ AVXcode: 1
42658: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) 43158: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
42759: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) 43259: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
4285a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) 4335a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
4295b: vcvtdq2ps Vps,Wdq | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) 4345b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
4305c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) 4355c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
4315d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) 4365d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
4325e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) 4375e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
@@ -447,7 +452,7 @@ AVXcode: 1
4476c: vpunpcklqdq Vx,Hx,Wx (66),(v1) 4526c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
4486d: vpunpckhqdq Vx,Hx,Wx (66),(v1) 4536d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
4496e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) 4546e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
4506f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqu Vx,Wx (F3) 4556f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev)
451# 0x0f 0x70-0x7f 456# 0x0f 0x70-0x7f
45270: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) 45770: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
45371: Grp12 (1A) 45871: Grp12 (1A)
@@ -458,14 +463,14 @@ AVXcode: 1
45876: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) 46376: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
459# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. 464# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
46077: emms | vzeroupper | vzeroall 46577: emms | vzeroupper | vzeroall
46178: VMREAD Ey,Gy 46678: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev)
46279: VMWRITE Gy,Ey 46779: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev)
4637a: 4687a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
4647b: 4697b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
4657c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) 4707c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
4667d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) 4717d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
4677e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) 4727e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
4687f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqu Wx,Vx (F3) 4737f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
469# 0x0f 0x80-0x8f 474# 0x0f 0x80-0x8f
470# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). 475# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
47180: JO Jz (f64) 47680: JO Jz (f64)
@@ -485,16 +490,16 @@ AVXcode: 1
4858e: JLE/JNG Jz (f64) 4908e: JLE/JNG Jz (f64)
4868f: JNLE/JG Jz (f64) 4918f: JNLE/JG Jz (f64)
487# 0x0f 0x90-0x9f 492# 0x0f 0x90-0x9f
48890: SETO Eb 49390: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
48991: SETNO Eb 49491: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
49092: SETB/C/NAE Eb 49592: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
49193: SETAE/NB/NC Eb 49693: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
49294: SETE/Z Eb 49794: SETE/Z Eb
49395: SETNE/NZ Eb 49895: SETNE/NZ Eb
49496: SETBE/NA Eb 49996: SETBE/NA Eb
49597: SETA/NBE Eb 50097: SETA/NBE Eb
49698: SETS Eb 50198: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
49799: SETNS Eb 50299: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
4989a: SETP/PE Eb 5039a: SETP/PE Eb
4999b: SETNP/PO Eb 5049b: SETNP/PO Eb
5009c: SETL/NGE Eb 5059c: SETL/NGE Eb
@@ -564,11 +569,11 @@ d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1)
564d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) 569d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
565d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) 570d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
566da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) 571da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
567db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) 572db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
568dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) 573dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
569dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) 574dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
570de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) 575de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
571df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) 576df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
572# 0x0f 0xe0-0xef 577# 0x0f 0xe0-0xef
573e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) 578e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
574e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) 579e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
@@ -576,16 +581,16 @@ e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1)
576e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) 581e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
577e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) 582e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
578e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) 583e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
579e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtpd2dq Vx,Wpd (F2) 584e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
580e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) 585e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
581e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) 586e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
582e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) 587e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
583ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) 588ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
584eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) 589eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
585ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) 590ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
586ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) 591ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
587ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) 592ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
588ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) 593ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
589# 0x0f 0xf0-0xff 594# 0x0f 0xf0-0xff
590f0: vlddqu Vx,Mx (F2) 595f0: vlddqu Vx,Mx (F2)
591f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) 596f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
@@ -626,81 +631,105 @@ AVXcode: 2
6260e: vtestps Vx,Wx (66),(v) 6310e: vtestps Vx,Wx (66),(v)
6270f: vtestpd Vx,Wx (66),(v) 6320f: vtestpd Vx,Wx (66),(v)
628# 0x0f 0x38 0x10-0x1f 633# 0x0f 0x38 0x10-0x1f
62910: pblendvb Vdq,Wdq (66) 63410: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
63011: 63511: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
63112: 63612: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
63213: vcvtph2ps Vx,Wx,Ib (66),(v) 63713: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
63314: blendvps Vdq,Wdq (66) 63814: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
63415: blendvpd Vdq,Wdq (66) 63915: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
63516: vpermps Vqq,Hqq,Wqq (66),(v) 64016: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
63617: vptest Vx,Wx (66) 64117: vptest Vx,Wx (66)
63718: vbroadcastss Vx,Wd (66),(v) 64218: vbroadcastss Vx,Wd (66),(v)
63819: vbroadcastsd Vqq,Wq (66),(v) 64319: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
6391a: vbroadcastf128 Vqq,Mdq (66),(v) 6441a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
6401b: 6451b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
6411c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) 6461c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
6421d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) 6471d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
6431e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) 6481e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
6441f: 6491f: vpabsq Vx,Wx (66),(ev)
645# 0x0f 0x38 0x20-0x2f 650# 0x0f 0x38 0x20-0x2f
64620: vpmovsxbw Vx,Ux/Mq (66),(v1) 65120: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
64721: vpmovsxbd Vx,Ux/Md (66),(v1) 65221: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
64822: vpmovsxbq Vx,Ux/Mw (66),(v1) 65322: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
64923: vpmovsxwd Vx,Ux/Mq (66),(v1) 65423: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
65024: vpmovsxwq Vx,Ux/Md (66),(v1) 65524: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
65125: vpmovsxdq Vx,Ux/Mq (66),(v1) 65625: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
65226: 65726: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
65327: 65827: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
65428: vpmuldq Vx,Hx,Wx (66),(v1) 65928: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
65529: vpcmpeqq Vx,Hx,Wx (66),(v1) 66029: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
6562a: vmovntdqa Vx,Mx (66),(v1) 6612a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
6572b: vpackusdw Vx,Hx,Wx (66),(v1) 6622b: vpackusdw Vx,Hx,Wx (66),(v1)
6582c: vmaskmovps Vx,Hx,Mx (66),(v) 6632c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
6592d: vmaskmovpd Vx,Hx,Mx (66),(v) 6642d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
6602e: vmaskmovps Mx,Hx,Vx (66),(v) 6652e: vmaskmovps Mx,Hx,Vx (66),(v)
6612f: vmaskmovpd Mx,Hx,Vx (66),(v) 6662f: vmaskmovpd Mx,Hx,Vx (66),(v)
662# 0x0f 0x38 0x30-0x3f 667# 0x0f 0x38 0x30-0x3f
66330: vpmovzxbw Vx,Ux/Mq (66),(v1) 66830: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
66431: vpmovzxbd Vx,Ux/Md (66),(v1) 66931: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
66532: vpmovzxbq Vx,Ux/Mw (66),(v1) 67032: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
66633: vpmovzxwd Vx,Ux/Mq (66),(v1) 67133: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
66734: vpmovzxwq Vx,Ux/Md (66),(v1) 67234: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
66835: vpmovzxdq Vx,Ux/Mq (66),(v1) 67335: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
66936: vpermd Vqq,Hqq,Wqq (66),(v) 67436: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
67037: vpcmpgtq Vx,Hx,Wx (66),(v1) 67537: vpcmpgtq Vx,Hx,Wx (66),(v1)
67138: vpminsb Vx,Hx,Wx (66),(v1) 67638: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
67239: vpminsd Vx,Hx,Wx (66),(v1) 67739: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
6733a: vpminuw Vx,Hx,Wx (66),(v1) 6783a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
6743b: vpminud Vx,Hx,Wx (66),(v1) 6793b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
6753c: vpmaxsb Vx,Hx,Wx (66),(v1) 6803c: vpmaxsb Vx,Hx,Wx (66),(v1)
6763d: vpmaxsd Vx,Hx,Wx (66),(v1) 6813d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
6773e: vpmaxuw Vx,Hx,Wx (66),(v1) 6823e: vpmaxuw Vx,Hx,Wx (66),(v1)
6783f: vpmaxud Vx,Hx,Wx (66),(v1) 6833f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
679# 0x0f 0x38 0x40-0x8f 684# 0x0f 0x38 0x40-0x8f
68040: vpmulld Vx,Hx,Wx (66),(v1) 68540: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
68141: vphminposuw Vdq,Wdq (66),(v1) 68641: vphminposuw Vdq,Wdq (66),(v1)
68242: 68742: vgetexpps/d Vx,Wx (66),(ev)
68343: 68843: vgetexpss/d Vx,Hx,Wx (66),(ev)
68444: 68944: vplzcntd/q Vx,Wx (66),(ev)
68545: vpsrlvd/q Vx,Hx,Wx (66),(v) 69045: vpsrlvd/q Vx,Hx,Wx (66),(v)
68646: vpsravd Vx,Hx,Wx (66),(v) 69146: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
68747: vpsllvd/q Vx,Hx,Wx (66),(v) 69247: vpsllvd/q Vx,Hx,Wx (66),(v)
688# Skip 0x48-0x57 693# Skip 0x48-0x4b
6944c: vrcp14ps/d Vpd,Wpd (66),(ev)
6954d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
6964e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
6974f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
698# Skip 0x50-0x57
68958: vpbroadcastd Vx,Wx (66),(v) 69958: vpbroadcastd Vx,Wx (66),(v)
69059: vpbroadcastq Vx,Wx (66),(v) 70059: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
6915a: vbroadcasti128 Vqq,Mdq (66),(v) 7015a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
692# Skip 0x5b-0x77 7025b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
703# Skip 0x5c-0x63
70464: vpblendmd/q Vx,Hx,Wx (66),(ev)
70565: vblendmps/d Vx,Hx,Wx (66),(ev)
70666: vpblendmb/w Vx,Hx,Wx (66),(ev)
707# Skip 0x67-0x74
70875: vpermi2b/w Vx,Hx,Wx (66),(ev)
70976: vpermi2d/q Vx,Hx,Wx (66),(ev)
71077: vpermi2ps/d Vx,Hx,Wx (66),(ev)
69378: vpbroadcastb Vx,Wx (66),(v) 71178: vpbroadcastb Vx,Wx (66),(v)
69479: vpbroadcastw Vx,Wx (66),(v) 71279: vpbroadcastw Vx,Wx (66),(v)
695# Skip 0x7a-0x7f 7137a: vpbroadcastb Vx,Rv (66),(ev)
7147b: vpbroadcastw Vx,Rv (66),(ev)
7157c: vpbroadcastd/q Vx,Rv (66),(ev)
7167d: vpermt2b/w Vx,Hx,Wx (66),(ev)
7177e: vpermt2d/q Vx,Hx,Wx (66),(ev)
7187f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
69680: INVEPT Gy,Mdq (66) 71980: INVEPT Gy,Mdq (66)
69781: INVPID Gy,Mdq (66) 72081: INVPID Gy,Mdq (66)
69882: INVPCID Gy,Mdq (66) 72182: INVPCID Gy,Mdq (66)
72283: vpmultishiftqb Vx,Hx,Wx (66),(ev)
72388: vexpandps/d Vpd,Wpd (66),(ev)
72489: vpexpandd/q Vx,Wx (66),(ev)
7258a: vcompressps/d Wx,Vx (66),(ev)
7268b: vpcompressd/q Wx,Vx (66),(ev)
6998c: vpmaskmovd/q Vx,Hx,Mx (66),(v) 7278c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
7288d: vpermb/w Vx,Hx,Wx (66),(ev)
7008e: vpmaskmovd/q Mx,Vx,Hx (66),(v) 7298e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
701# 0x0f 0x38 0x90-0xbf (FMA) 730# 0x0f 0x38 0x90-0xbf (FMA)
70290: vgatherdd/q Vx,Hx,Wx (66),(v) 73190: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
70391: vgatherqd/q Vx,Hx,Wx (66),(v) 73291: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
70492: vgatherdps/d Vx,Hx,Wx (66),(v) 73392: vgatherdps/d Vx,Hx,Wx (66),(v)
70593: vgatherqps/d Vx,Hx,Wx (66),(v) 73493: vgatherqps/d Vx,Hx,Wx (66),(v)
70694: 73594:
@@ -715,6 +744,10 @@ AVXcode: 2
7159d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) 7449d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
7169e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) 7459e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
7179f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) 7469f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
747a0: vpscatterdd/q Wx,Vx (66),(ev)
748a1: vpscatterqd/q Wx,Vx (66),(ev)
749a2: vscatterdps/d Wx,Vx (66),(ev)
750a3: vscatterqps/d Wx,Vx (66),(ev)
718a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) 751a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
719a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) 752a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
720a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) 753a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
@@ -725,6 +758,8 @@ ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
725ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) 758ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
726ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) 759ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
727af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) 760af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
761b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
762b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
728b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) 763b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
729b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) 764b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
730b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) 765b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
@@ -736,12 +771,15 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
736be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) 771be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
737bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) 772bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
738# 0x0f 0x38 0xc0-0xff 773# 0x0f 0x38 0xc0-0xff
739c8: sha1nexte Vdq,Wdq 774c4: vpconflictd/q Vx,Wx (66),(ev)
775c6: Grp18 (1A)
776c7: Grp19 (1A)
777c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
740c9: sha1msg1 Vdq,Wdq 778c9: sha1msg1 Vdq,Wdq
741ca: sha1msg2 Vdq,Wdq 779ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
742cb: sha256rnds2 Vdq,Wdq 780cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
743cc: sha256msg1 Vdq,Wdq 781cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
744cd: sha256msg2 Vdq,Wdq 782cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
745db: VAESIMC Vdq,Wdq (66),(v1) 783db: VAESIMC Vdq,Wdq (66),(v1)
746dc: VAESENC Vdq,Hdq,Wdq (66),(v1) 784dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
747dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) 785dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -763,15 +801,15 @@ AVXcode: 3
76300: vpermq Vqq,Wqq,Ib (66),(v) 80100: vpermq Vqq,Wqq,Ib (66),(v)
76401: vpermpd Vqq,Wqq,Ib (66),(v) 80201: vpermpd Vqq,Wqq,Ib (66),(v)
76502: vpblendd Vx,Hx,Wx,Ib (66),(v) 80302: vpblendd Vx,Hx,Wx,Ib (66),(v)
76603: 80403: valignd/q Vx,Hx,Wx,Ib (66),(ev)
76704: vpermilps Vx,Wx,Ib (66),(v) 80504: vpermilps Vx,Wx,Ib (66),(v)
76805: vpermilpd Vx,Wx,Ib (66),(v) 80605: vpermilpd Vx,Wx,Ib (66),(v)
76906: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) 80706: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
77007: 80807:
77108: vroundps Vx,Wx,Ib (66) 80908: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
77209: vroundpd Vx,Wx,Ib (66) 81009: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
7730a: vroundss Vss,Wss,Ib (66),(v1) 8110a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
7740b: vroundsd Vsd,Wsd,Ib (66),(v1) 8120b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
7750c: vblendps Vx,Hx,Wx,Ib (66) 8130c: vblendps Vx,Hx,Wx,Ib (66)
7760d: vblendpd Vx,Hx,Wx,Ib (66) 8140d: vblendpd Vx,Hx,Wx,Ib (66)
7770e: vpblendw Vx,Hx,Wx,Ib (66),(v1) 8150e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
@@ -780,26 +818,51 @@ AVXcode: 3
78015: vpextrw Rd/Mw,Vdq,Ib (66),(v1) 81815: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
78116: vpextrd/q Ey,Vdq,Ib (66),(v1) 81916: vpextrd/q Ey,Vdq,Ib (66),(v1)
78217: vextractps Ed,Vdq,Ib (66),(v1) 82017: vextractps Ed,Vdq,Ib (66),(v1)
78318: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) 82118: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
78419: vextractf128 Wdq,Vqq,Ib (66),(v) 82219: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
8231a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
8241b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
7851d: vcvtps2ph Wx,Vx,Ib (66),(v) 8251d: vcvtps2ph Wx,Vx,Ib (66),(v)
8261e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
8271f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
78620: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) 82820: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
78721: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) 82921: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
78822: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) 83022: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
78938: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) 83123: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
79039: vextracti128 Wdq,Vqq,Ib (66),(v) 83225: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
83326: vgetmantps/d Vx,Wx,Ib (66),(ev)
83427: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
83530: kshiftrb/w Vk,Uk,Ib (66),(v)
83631: kshiftrd/q Vk,Uk,Ib (66),(v)
83732: kshiftlb/w Vk,Uk,Ib (66),(v)
83833: kshiftld/q Vk,Uk,Ib (66),(v)
83938: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
84039: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
8413a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
8423b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
8433e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
8443f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
79140: vdpps Vx,Hx,Wx,Ib (66) 84540: vdpps Vx,Hx,Wx,Ib (66)
79241: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) 84641: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
79342: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) 84742: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
84843: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
79444: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) 84944: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
79546: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) 85046: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
7964a: vblendvps Vx,Hx,Wx,Lx (66),(v) 8514a: vblendvps Vx,Hx,Wx,Lx (66),(v)
7974b: vblendvpd Vx,Hx,Wx,Lx (66),(v) 8524b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
7984c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) 8534c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
85450: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
85551: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
85654: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
85755: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
85856: vreduceps/d Vx,Wx,Ib (66),(ev)
85957: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
79960: vpcmpestrm Vdq,Wdq,Ib (66),(v1) 86060: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
80061: vpcmpestri Vdq,Wdq,Ib (66),(v1) 86161: vpcmpestri Vdq,Wdq,Ib (66),(v1)
80162: vpcmpistrm Vdq,Wdq,Ib (66),(v1) 86262: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
80263: vpcmpistri Vdq,Wdq,Ib (66),(v1) 86363: vpcmpistri Vdq,Wdq,Ib (66),(v1)
86466: vfpclassps/d Vk,Wx,Ib (66),(ev)
86567: vfpclassss/d Vk,Wx,Ib (66),(ev)
803cc: sha1rnds4 Vdq,Wdq,Ib 866cc: sha1rnds4 Vdq,Wdq,Ib
804df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) 867df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
805f0: RORX Gy,Ey,Ib (F2),(v) 868f0: RORX Gy,Ey,Ib (F2),(v)
@@ -927,8 +990,10 @@ GrpTable: Grp12
927EndTable 990EndTable
928 991
929GrpTable: Grp13 992GrpTable: Grp13
9930: vprord/q Hx,Wx,Ib (66),(ev)
9941: vprold/q Hx,Wx,Ib (66),(ev)
9302: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) 9952: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
9314: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) 9964: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
9326: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) 9976: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
933EndTable 998EndTable
934 999
@@ -947,7 +1012,7 @@ GrpTable: Grp15
9474: XSAVE 10124: XSAVE
9485: XRSTOR | lfence (11B) 10135: XRSTOR | lfence (11B)
9496: XSAVEOPT | clwb (66) | mfence (11B) 10146: XSAVEOPT | clwb (66) | mfence (11B)
9507: clflush | clflushopt (66) | sfence (11B) | pcommit (66),(11B) 10157: clflush | clflushopt (66) | sfence (11B)
951EndTable 1016EndTable
952 1017
953GrpTable: Grp16 1018GrpTable: Grp16
@@ -963,6 +1028,20 @@ GrpTable: Grp17
9633: BLSI By,Ey (v) 10283: BLSI By,Ey (v)
964EndTable 1029EndTable
965 1030
1031GrpTable: Grp18
10321: vgatherpf0dps/d Wx (66),(ev)
10332: vgatherpf1dps/d Wx (66),(ev)
10345: vscatterpf0dps/d Wx (66),(ev)
10356: vscatterpf1dps/d Wx (66),(ev)
1036EndTable
1037
1038GrpTable: Grp19
10391: vgatherpf0qps/d Wx (66),(ev)
10402: vgatherpf1qps/d Wx (66),(ev)
10415: vscatterpf0qps/d Wx (66),(ev)
10426: vscatterpf1qps/d Wx (66),(ev)
1043EndTable
1044
966# AMD's Prefetch Group 1045# AMD's Prefetch Group
967GrpTable: GrpP 1046GrpTable: GrpP
9680: PREFETCH 10470: PREFETCH
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 25d803148f5c..bd09d0effef8 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28#include <string.h> 28#include <string.h>
29#include <stdlib.h>
29#include <subcmd/parse-options.h> 30#include <subcmd/parse-options.h>
30 31
31#include "builtin.h" 32#include "builtin.h"
@@ -106,6 +107,12 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,
106 insn->offset < func->offset + func->len; \ 107 insn->offset < func->offset + func->len; \
107 insn = list_next_entry(insn, list)) 108 insn = list_next_entry(insn, list))
108 109
110#define func_for_each_insn_continue_reverse(file, func, insn) \
111 for (insn = list_prev_entry(insn, list); \
112 &insn->list != &file->insn_list && \
113 insn->sec == func->sec && insn->offset >= func->offset; \
114 insn = list_prev_entry(insn, list))
115
109#define sec_for_each_insn_from(file, insn) \ 116#define sec_for_each_insn_from(file, insn) \
110 for (; insn; insn = next_insn_same_sec(file, insn)) 117 for (; insn; insn = next_insn_same_sec(file, insn))
111 118
@@ -663,65 +670,95 @@ static int add_switch_table(struct objtool_file *file, struct symbol *func,
663 return 0; 670 return 0;
664} 671}
665 672
666static int add_func_switch_tables(struct objtool_file *file, 673/*
667 struct symbol *func) 674 * find_switch_table() - Given a dynamic jump, find the switch jump table in
675 * .rodata associated with it.
676 *
677 * There are 3 basic patterns:
678 *
679 * 1. jmpq *[rodata addr](,%reg,8)
680 *
681 * This is the most common case by far. It jumps to an address in a simple
682 * jump table which is stored in .rodata.
683 *
684 * 2. jmpq *[rodata addr](%rip)
685 *
686 * This is caused by a rare GCC quirk, currently only seen in three driver
687 * functions in the kernel, only with certain obscure non-distro configs.
688 *
689 * As part of an optimization, GCC makes a copy of an existing switch jump
690 * table, modifies it, and then hard-codes the jump (albeit with an indirect
691 * jump) to use a single entry in the table. The rest of the jump table and
692 * some of its jump targets remain as dead code.
693 *
694 * In such a case we can just crudely ignore all unreachable instruction
695 * warnings for the entire object file. Ideally we would just ignore them
696 * for the function, but that would require redesigning the code quite a
697 * bit. And honestly that's just not worth doing: unreachable instruction
698 * warnings are of questionable value anyway, and this is such a rare issue.
699 *
700 * 3. mov [rodata addr],%reg1
701 * ... some instructions ...
702 * jmpq *(%reg1,%reg2,8)
703 *
704 * This is a fairly uncommon pattern which is new for GCC 6. As of this
705 * writing, there are 11 occurrences of it in the allmodconfig kernel.
706 *
707 * TODO: Once we have DWARF CFI and smarter instruction decoding logic,
708 * ensure the same register is used in the mov and jump instructions.
709 */
710static struct rela *find_switch_table(struct objtool_file *file,
711 struct symbol *func,
712 struct instruction *insn)
668{ 713{
669 struct instruction *insn, *prev_jump; 714 struct rela *text_rela, *rodata_rela;
670 struct rela *text_rela, *rodata_rela, *prev_rela;
671 int ret;
672 715
673 prev_jump = NULL; 716 text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
717 if (text_rela && text_rela->sym == file->rodata->sym) {
718 /* case 1 */
719 rodata_rela = find_rela_by_dest(file->rodata,
720 text_rela->addend);
721 if (rodata_rela)
722 return rodata_rela;
674 723
675 func_for_each_insn(file, func, insn) { 724 /* case 2 */
676 if (insn->type != INSN_JUMP_DYNAMIC) 725 rodata_rela = find_rela_by_dest(file->rodata,
677 continue; 726 text_rela->addend + 4);
727 if (!rodata_rela)
728 return NULL;
729 file->ignore_unreachables = true;
730 return rodata_rela;
731 }
732
733 /* case 3 */
734 func_for_each_insn_continue_reverse(file, func, insn) {
735 if (insn->type == INSN_JUMP_UNCONDITIONAL ||
736 insn->type == INSN_JUMP_DYNAMIC)
737 break;
678 738
679 text_rela = find_rela_by_dest_range(insn->sec, insn->offset, 739 text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
680 insn->len); 740 insn->len);
681 if (!text_rela || text_rela->sym != file->rodata->sym) 741 if (text_rela && text_rela->sym == file->rodata->sym)
682 continue; 742 return find_rela_by_dest(file->rodata,
743 text_rela->addend);
744 }
683 745
684 /* common case: jmpq *[addr](,%rax,8) */ 746 return NULL;
685 rodata_rela = find_rela_by_dest(file->rodata, 747}
686 text_rela->addend);
687 748
688 /* 749static int add_func_switch_tables(struct objtool_file *file,
689 * rare case: jmpq *[addr](%rip) 750 struct symbol *func)
690 * 751{
691 * This check is for a rare gcc quirk, currently only seen in 752 struct instruction *insn, *prev_jump = NULL;
692 * three driver functions in the kernel, only with certain 753 struct rela *rela, *prev_rela = NULL;
693 * obscure non-distro configs. 754 int ret;
694 *
695 * As part of an optimization, gcc makes a copy of an existing
696 * switch jump table, modifies it, and then hard-codes the jump
697 * (albeit with an indirect jump) to use a single entry in the
698 * table. The rest of the jump table and some of its jump
699 * targets remain as dead code.
700 *
701 * In such a case we can just crudely ignore all unreachable
702 * instruction warnings for the entire object file. Ideally we
703 * would just ignore them for the function, but that would
704 * require redesigning the code quite a bit. And honestly
705 * that's just not worth doing: unreachable instruction
706 * warnings are of questionable value anyway, and this is such
707 * a rare issue.
708 *
709 * kbuild reports:
710 * - https://lkml.kernel.org/r/201603231906.LWcVUpxm%25fengguang.wu@intel.com
711 * - https://lkml.kernel.org/r/201603271114.K9i45biy%25fengguang.wu@intel.com
712 * - https://lkml.kernel.org/r/201603291058.zuJ6ben1%25fengguang.wu@intel.com
713 *
714 * gcc bug:
715 * - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70604
716 */
717 if (!rodata_rela) {
718 rodata_rela = find_rela_by_dest(file->rodata,
719 text_rela->addend + 4);
720 if (rodata_rela)
721 file->ignore_unreachables = true;
722 }
723 755
724 if (!rodata_rela) 756 func_for_each_insn(file, func, insn) {
757 if (insn->type != INSN_JUMP_DYNAMIC)
758 continue;
759
760 rela = find_switch_table(file, func, insn);
761 if (!rela)
725 continue; 762 continue;
726 763
727 /* 764 /*
@@ -731,13 +768,13 @@ static int add_func_switch_tables(struct objtool_file *file,
731 */ 768 */
732 if (prev_jump) { 769 if (prev_jump) {
733 ret = add_switch_table(file, func, prev_jump, prev_rela, 770 ret = add_switch_table(file, func, prev_jump, prev_rela,
734 rodata_rela); 771 rela);
735 if (ret) 772 if (ret)
736 return ret; 773 return ret;
737 } 774 }
738 775
739 prev_jump = insn; 776 prev_jump = insn;
740 prev_rela = rodata_rela; 777 prev_rela = rela;
741 } 778 }
742 779
743 if (prev_jump) { 780 if (prev_jump) {
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index e11f6b69cce6..0d7983ac63ef 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -30,6 +30,13 @@
30#include "elf.h" 30#include "elf.h"
31#include "warn.h" 31#include "warn.h"
32 32
33/*
34 * Fallback for systems without this "read, mmaping if possible" cmd.
35 */
36#ifndef ELF_C_READ_MMAP
37#define ELF_C_READ_MMAP ELF_C_READ
38#endif
39
33struct section *find_section_by_name(struct elf *elf, const char *name) 40struct section *find_section_by_name(struct elf *elf, const char *name)
34{ 41{
35 struct section *sec; 42 struct section *sec;
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 3d1bb802dbf4..3db3db9278be 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -30,3 +30,4 @@ config.mak.autogen
30*.pyo 30*.pyo
31.config-detected 31.config-detected
32util/intel-pt-decoder/inat-tables.c 32util/intel-pt-decoder/inat-tables.c
33arch/*/include/generated/
diff --git a/tools/perf/Documentation/android.txt b/tools/perf/Documentation/android.txt
index 8484c3a04a6a..24a59998fc91 100644
--- a/tools/perf/Documentation/android.txt
+++ b/tools/perf/Documentation/android.txt
@@ -12,14 +12,14 @@ Set the NDK variable to point to the path where you installed the NDK:
12 12
132. Set cross-compiling environment variables for NDK toolchain and sysroot. 132. Set cross-compiling environment variables for NDK toolchain and sysroot.
14For arm: 14For arm:
15 export NDK_TOOLCHAIN=${NDK}/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi- 15 export NDK_TOOLCHAIN=${NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
16 export NDK_SYSROOT=${NDK}/platforms/android-9/arch-arm 16 export NDK_SYSROOT=${NDK}/platforms/android-24/arch-arm
17For x86: 17For x86:
18 export NDK_TOOLCHAIN=${NDK}/toolchains/x86-4.6/prebuilt/linux-x86/bin/i686-linux-android- 18 export NDK_TOOLCHAIN=${NDK}/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-
19 export NDK_SYSROOT=${NDK}/platforms/android-9/arch-x86 19 export NDK_SYSROOT=${NDK}/platforms/android-24/arch-x86
20 20
21This method is not working for Android NDK versions up to Revision 8b. 21This method is only tested for Android NDK versions Revision 11b and later.
22perf uses some bionic enhancements that are not included in these NDK versions. 22perf uses some bionic enhancements that are not included in prior NDK versions.
23You can use method (b) described below instead. 23You can use method (b) described below instead.
24 24
25(b). Use the Android source tree 25(b). Use the Android source tree
@@ -49,9 +49,9 @@ II. Compile perf for Android
49------------------------------------------------ 49------------------------------------------------
50You need to run make with the NDK toolchain and sysroot defined above: 50You need to run make with the NDK toolchain and sysroot defined above:
51For arm: 51For arm:
52 make ARCH=arm CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}" 52 make WERROR=0 ARCH=arm CROSS_COMPILE=${NDK_TOOLCHAIN} EXTRA_CFLAGS="-pie --sysroot=${NDK_SYSROOT}"
53For x86: 53For x86:
54 make ARCH=x86 CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}" 54 make WERROR=0 ARCH=x86 CROSS_COMPILE=${NDK_TOOLCHAIN} EXTRA_CFLAGS="-pie --sysroot=${NDK_SYSROOT}"
55 55
56III. Install perf 56III. Install perf
57----------------------------------------------- 57-----------------------------------------------
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index 778f54d4d0bd..8ffbd272952d 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -61,6 +61,13 @@ OPTIONS
61 61
62--stdio:: Use the stdio interface. 62--stdio:: Use the stdio interface.
63 63
64--stdio-color::
65 'always', 'never' or 'auto', allowing configuring color output
66 via the command line, in addition to via "color.ui" .perfconfig.
67 Use '--stdio-color always' to generate color even when redirecting
68 to a pipe or file. Using just '--stdio-color' is equivalent to
69 using 'always'.
70
64--tui:: Use the TUI interface. Use of --tui requires a tty, if one is not 71--tui:: Use the TUI interface. Use of --tui requires a tty, if one is not
65 present, as when piping to other commands, the stdio interface is 72 present, as when piping to other commands, the stdio interface is
66 used. This interfaces starts by centering on the line with more 73 used. This interfaces starts by centering on the line with more
diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt
index dd07b55f58d8..058064db39d2 100644
--- a/tools/perf/Documentation/perf-buildid-cache.txt
+++ b/tools/perf/Documentation/perf-buildid-cache.txt
@@ -15,6 +15,9 @@ DESCRIPTION
15This command manages the build-id cache. It can add, remove, update and purge 15This command manages the build-id cache. It can add, remove, update and purge
16files to/from the cache. In the future it should as well set upper limits for 16files to/from the cache. In the future it should as well set upper limits for
17the space used by the cache, etc. 17the space used by the cache, etc.
18This also scans the target binary for SDT (Statically Defined Tracing) and
19record it along with the buildid-cache, which will be used by perf-probe.
20For more details, see linkperf:perf-probe[1].
18 21
19OPTIONS 22OPTIONS
20------- 23-------
diff --git a/tools/perf/Documentation/perf-data.txt b/tools/perf/Documentation/perf-data.txt
index be8fa1a0a97e..f0796a47dfa3 100644
--- a/tools/perf/Documentation/perf-data.txt
+++ b/tools/perf/Documentation/perf-data.txt
@@ -34,6 +34,10 @@ OPTIONS for 'convert'
34--verbose:: 34--verbose::
35 Be more verbose (show counter open errors, etc). 35 Be more verbose (show counter open errors, etc).
36 36
37--all::
38 Convert all events, including non-sample events (comm, fork, ...), to output.
39 Default is off, only convert samples.
40
37SEE ALSO 41SEE ALSO
38-------- 42--------
39linkperf:perf[1] 43linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-mem.txt b/tools/perf/Documentation/perf-mem.txt
index 1d6092c460dd..73496320fca3 100644
--- a/tools/perf/Documentation/perf-mem.txt
+++ b/tools/perf/Documentation/perf-mem.txt
@@ -56,6 +56,9 @@ OPTIONS
56--all-user:: 56--all-user::
57 Configure all used events to run in user space. 57 Configure all used events to run in user space.
58 58
59--ldload::
60 Specify desired latency for loads event.
61
59SEE ALSO 62SEE ALSO
60-------- 63--------
61linkperf:perf-record[1], linkperf:perf-report[1] 64linkperf:perf-record[1], linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 3a8a9ba2b041..736da44596e4 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -67,7 +67,10 @@ OPTIONS
67 67
68-l:: 68-l::
69--list[=[GROUP:]EVENT]:: 69--list[=[GROUP:]EVENT]::
70 List up current probe events. This can also accept filtering patterns of event names. 70 List up current probe events. This can also accept filtering patterns of
71 event names.
72 When this is used with --cache, perf shows all cached probes instead of
73 the live probes.
71 74
72-L:: 75-L::
73--line=:: 76--line=::
@@ -109,6 +112,12 @@ OPTIONS
109 Dry run. With this option, --add and --del doesn't execute actual 112 Dry run. With this option, --add and --del doesn't execute actual
110 adding and removal operations. 113 adding and removal operations.
111 114
115--cache::
116 (With --add) Cache the probes. Any events which successfully added
117 are also stored in the cache file.
118 (With --list) Show cached probes.
119 (With --del) Remove cached probes.
120
112--max-probes=NUM:: 121--max-probes=NUM::
113 Set the maximum number of probe points for an event. Default is 128. 122 Set the maximum number of probe points for an event. Default is 128.
114 123
@@ -134,19 +143,30 @@ PROBE SYNTAX
134Probe points are defined by following syntax. 143Probe points are defined by following syntax.
135 144
136 1) Define event based on function name 145 1) Define event based on function name
137 [EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...] 146 [[GROUP:]EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]
138 147
139 2) Define event based on source file with line number 148 2) Define event based on source file with line number
140 [EVENT=]SRC:ALN [ARG ...] 149 [[GROUP:]EVENT=]SRC:ALN [ARG ...]
141 150
142 3) Define event based on source file with lazy pattern 151 3) Define event based on source file with lazy pattern
143 [EVENT=]SRC;PTN [ARG ...] 152 [[GROUP:]EVENT=]SRC;PTN [ARG ...]
144 153
154 4) Pre-defined SDT events or cached event with name
155 %[sdt_PROVIDER:]SDTEVENT
156 or,
157 sdt_PROVIDER:SDTEVENT
145 158
146'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'. 159'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
160Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
161modules.
147'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function. 162'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function.
148It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern. 163It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
149'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT). 164'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
165'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by user SDT (Statically Defined Tracing) or the pre-cached probes with event name.
166Note that before using the SDT event, the target binary (on which SDT events are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT events as cached events.
167
168For details of the SDT, see below.
169https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
150 170
151PROBE ARGUMENT 171PROBE ARGUMENT
152-------------- 172--------------
@@ -226,4 +246,4 @@ Add probes at malloc() function on libc
226 246
227SEE ALSO 247SEE ALSO
228-------- 248--------
229linkperf:perf-trace[1], linkperf:perf-record[1] 249linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 8dbee832abd9..69966abf65d1 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -360,6 +360,35 @@ particular perf.data snapshot should be kept or not.
360 360
361Implies --timestamp-filename, --no-buildid and --no-buildid-cache. 361Implies --timestamp-filename, --no-buildid and --no-buildid-cache.
362 362
363--dry-run::
364Parse options then exit. --dry-run can be used to detect errors in cmdline
365options.
366
367'perf record --dry-run -e' can act as a BPF script compiler if llvm.dump-obj
368in config file is set to true.
369
370--tail-synthesize::
371Instead of collecting non-sample events (for example, fork, comm, mmap) at
372the beginning of record, collect them during finalizing an output file.
373The collected non-sample events reflects the status of the system when
374record is finished.
375
376--overwrite::
377Makes all events use an overwritable ring buffer. An overwritable ring
378buffer works like a flight recorder: when it gets full, the kernel will
379overwrite the oldest records, that thus will never make it to the
380perf.data file.
381
382When '--overwrite' and '--switch-output' are used perf records and drops
383events until it receives a signal, meaning that something unusual was
384detected that warrants taking a snapshot of the most current events,
385those fitting in the ring buffer at that moment.
386
387'overwrite' attribute can also be set or canceled for an event using
388config terms. For example: 'cycles/overwrite/' and 'instructions/no-overwrite/'.
389
390Implies --tail-synthesize.
391
363SEE ALSO 392SEE ALSO
364-------- 393--------
365linkperf:perf-stat[1], linkperf:perf-list[1] 394linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 9cbddc290aff..2d1746295abf 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -265,6 +265,13 @@ OPTIONS
265 265
266--stdio:: Use the stdio interface. 266--stdio:: Use the stdio interface.
267 267
268--stdio-color::
269 'always', 'never' or 'auto', allowing configuring color output
270 via the command line, in addition to via "color.ui" .perfconfig.
271 Use '--stdio-color always' to generate color even when redirecting
272 to a pipe or file. Using just '--stdio-color' is equivalent to
273 using 'always'.
274
268--tui:: Use the TUI interface, that is integrated with annotate and allows 275--tui:: Use the TUI interface, that is integrated with annotate and allows
269 zooming into DSOs or threads, among other features. Use of --tui 276 zooming into DSOs or threads, among other features. Use of --tui
270 requires a tty, if one is not present, as when piping to other 277 requires a tty, if one is not present, as when piping to other
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 4fc44c75263f..1f6c70594f0f 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -119,13 +119,13 @@ OPTIONS
119 srcline, period, iregs, brstack, brstacksym, flags. 119 srcline, period, iregs, brstack, brstacksym, flags.
120 Field list can be prepended with the type, trace, sw or hw, 120 Field list can be prepended with the type, trace, sw or hw,
121 to indicate to which event type the field list applies. 121 to indicate to which event type the field list applies.
122 e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace 122 e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
123 123
124 perf script -f <fields> 124 perf script -F <fields>
125 125
126 is equivalent to: 126 is equivalent to:
127 127
128 perf script -f trace:<fields> -f sw:<fields> -f hw:<fields> 128 perf script -F trace:<fields> -F sw:<fields> -F hw:<fields>
129 129
130 i.e., the specified fields apply to all event types if the type string 130 i.e., the specified fields apply to all event types if the type string
131 is not given. 131 is not given.
@@ -133,9 +133,9 @@ OPTIONS
133 The arguments are processed in the order received. A later usage can 133 The arguments are processed in the order received. A later usage can
134 reset a prior request. e.g.: 134 reset a prior request. e.g.:
135 135
136 -f trace: -f comm,tid,time,ip,sym 136 -F trace: -F comm,tid,time,ip,sym
137 137
138 The first -f suppresses trace events (field list is ""), but then the 138 The first -F suppresses trace events (field list is ""), but then the
139 second invocation sets the fields to comm,tid,time,ip,sym. In this case a 139 second invocation sets the fields to comm,tid,time,ip,sym. In this case a
140 warning is given to the user: 140 warning is given to the user:
141 141
@@ -143,9 +143,9 @@ OPTIONS
143 143
144 Alternatively, consider the order: 144 Alternatively, consider the order:
145 145
146 -f comm,tid,time,ip,sym -f trace: 146 -F comm,tid,time,ip,sym -F trace:
147 147
148 The first -f sets the fields for all events and the second -f 148 The first -F sets the fields for all events and the second -F
149 suppresses trace events. The user is given a warning message about 149 suppresses trace events. The user is given a warning message about
150 the override, and the result of the above is that only S/W and H/W 150 the override, and the result of the above is that only S/W and H/W
151 events are displayed with the given fields. 151 events are displayed with the given fields.
@@ -154,14 +154,14 @@ OPTIONS
154 event type, a message is displayed to the user that the option is 154 event type, a message is displayed to the user that the option is
155 ignored for that type. For example: 155 ignored for that type. For example:
156 156
157 $ perf script -f comm,tid,trace 157 $ perf script -F comm,tid,trace
158 'trace' not valid for hardware events. Ignoring. 158 'trace' not valid for hardware events. Ignoring.
159 'trace' not valid for software events. Ignoring. 159 'trace' not valid for software events. Ignoring.
160 160
161 Alternatively, if the type is given an invalid field is specified it 161 Alternatively, if the type is given an invalid field is specified it
162 is an error. For example: 162 is an error. For example:
163 163
164 perf script -v -f sw:comm,tid,trace 164 perf script -v -F sw:comm,tid,trace
165 'trace' not valid for software events. 165 'trace' not valid for software events.
166 166
167 At this point usage is displayed, and perf-script exits. 167 At this point usage is displayed, and perf-script exits.
@@ -170,10 +170,19 @@ OPTIONS
170 Trace decoding. The flags are "bcrosyiABEx" which stand for branch, 170 Trace decoding. The flags are "bcrosyiABEx" which stand for branch,
171 call, return, conditional, system, asynchronous, interrupt, 171 call, return, conditional, system, asynchronous, interrupt,
172 transaction abort, trace begin, trace end, and in transaction, 172 transaction abort, trace begin, trace end, and in transaction,
173 respectively. 173 respectively. Known combinations of flags are printed more nicely e.g.
174 "call" for "bc", "return" for "br", "jcc" for "bo", "jmp" for "b",
175 "int" for "bci", "iret" for "bri", "syscall" for "bcs", "sysret" for "brs",
176 "async" for "by", "hw int" for "bcyi", "tx abrt" for "bA", "tr strt" for "bB",
177 "tr end" for "bE". However the "x" flag will be display separately in those
178 cases e.g. "jcc (x)" for a condition branch within a transaction.
179
180 The callindent field is synthesized and may have a value when
181 Instruction Trace decoding. For calls and returns, it will display the
182 name of the symbol indented with spaces to reflect the stack depth.
174 183
175 Finally, a user may not set fields to none for all event types. 184 Finally, a user may not set fields to none for all event types.
176 i.e., -f "" is not allowed. 185 i.e., -F "" is not allowed.
177 186
178 The brstack output includes branch related information with raw addresses using the 187 The brstack output includes branch related information with raw addresses using the
179 /v/v/v/v/ syntax in the following order: 188 /v/v/v/v/ syntax in the following order:
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 04f23b404bbc..d96ccd4844df 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -204,6 +204,38 @@ Aggregate counts per physical processor for system-wide mode measurements.
204--no-aggr:: 204--no-aggr::
205Do not aggregate counts across all monitored CPUs. 205Do not aggregate counts across all monitored CPUs.
206 206
207--topdown::
208Print top down level 1 metrics if supported by the CPU. This allows to
209determine bottle necks in the CPU pipeline for CPU bound workloads,
210by breaking the cycles consumed down into frontend bound, backend bound,
211bad speculation and retiring.
212
213Frontend bound means that the CPU cannot fetch and decode instructions fast
214enough. Backend bound means that computation or memory access is the bottle
215neck. Bad Speculation means that the CPU wasted cycles due to branch
216mispredictions and similar issues. Retiring means that the CPU computed without
217an apparently bottleneck. The bottleneck is only the real bottleneck
218if the workload is actually bound by the CPU and not by something else.
219
220For best results it is usually a good idea to use it with interval
221mode like -I 1000, as the bottleneck of workloads can change often.
222
223The top down metrics are collected per core instead of per
224CPU thread. Per core mode is automatically enabled
225and -a (global monitoring) is needed, requiring root rights or
226perf.perf_event_paranoid=-1.
227
228Topdown uses the full Performance Monitoring Unit, and needs
229disabling of the NMI watchdog (as root):
230echo 0 > /proc/sys/kernel/nmi_watchdog
231for best results. Otherwise the bottlenecks may be inconsistent
232on workload with changing phases.
233
234This enables --metric-only, unless overriden with --no-metric-only.
235
236To interpret the results it is usually needed to know on which
237CPUs the workload runs on. If needed the CPUs can be forced using
238taskset.
207 239
208EXAMPLES 240EXAMPLES
209-------- 241--------
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
index 31a5c3ea7f74..b329c65d7f40 100644
--- a/tools/perf/Documentation/perf-test.txt
+++ b/tools/perf/Documentation/perf-test.txt
@@ -30,3 +30,7 @@ OPTIONS
30-v:: 30-v::
31--verbose:: 31--verbose::
32 Be more verbose. 32 Be more verbose.
33
34-F::
35--dont-fork::
36 Do not fork child for each test, run all tests within single process.
diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt
new file mode 100644
index 000000000000..fdc99fe6bbc3
--- /dev/null
+++ b/tools/perf/Documentation/perf.data-file-format.txt
@@ -0,0 +1,442 @@
1perf.data format
2
3Uptodate as of v4.7
4
5This document describes the on-disk perf.data format, generated by perf record
6or perf inject and consumed by the other perf tools.
7
8On a high level perf.data contains the events generated by the PMUs, plus metadata.
9
10All fields are in native-endian of the machine that generated the perf.data.
11
12When perf is writing to a pipe it uses a special version of the file
13format that does not rely on seeking to adjust data offsets. This
14format is not described here. The pipe version can be converted to
15normal perf.data with perf inject.
16
17The file starts with a perf_header:
18
19struct perf_header {
20 char magic[8]; /* PERFILE2 */
21 uint64_t size; /* size of the header */
22 uint64_t attr_size; /* size of an attribute in attrs */
23 struct perf_file_section attrs;
24 struct perf_file_section data;
25 struct perf_file_section event_types;
26 uint64_t flags;
27 uint64_t flags1[3];
28};
29
30The magic number identifies the perf file and the version. Current perf versions
31use PERFILE2. Old perf versions generated a version 1 format (PERFFILE). Version 1
32is not described here. The magic number also identifies the endian. When the
33magic value is 64bit byte swapped compared the file is in non-native
34endian.
35
36A perf_file_section contains a pointer to another section of the perf file.
37The header contains three such pointers: for attributes, data and event types.
38
39struct perf_file_section {
40 uint64_t offset; /* offset from start of file */
41 uint64_t size; /* size of the section */
42};
43
44Flags section:
45
46The header is followed by different optional headers, described by the bits set
47in flags. Only headers for which the bit is set are included. Each header
48consists of a perf_file_section located after the initial header.
49The respective perf_file_section points to the data of the additional
50header and defines its size.
51
52Some headers consist of strings, which are defined like this:
53
54struct perf_header_string {
55 uint32_t len;
56 char string[len]; /* zero terminated */
57};
58
59Some headers consist of a sequence of strings, which start with a
60
61struct perf_header_string_list {
62 uint32_t nr;
63 struct perf_header_string strings[nr]; /* variable length records */
64};
65
66The bits are the flags bits in a 256 bit bitmap starting with
67flags. These define the valid bits:
68
69 HEADER_RESERVED = 0, /* always cleared */
70 HEADER_FIRST_FEATURE = 1,
71 HEADER_TRACING_DATA = 1,
72
73Describe me.
74
75 HEADER_BUILD_ID = 2,
76
77The header consists of an sequence of build_id_event. The size of each record
78is defined by header.size (see perf_event.h). Each event defines a ELF build id
79for a executable file name for a pid. An ELF build id is a unique identifier
80assigned by the linker to an executable.
81
82struct build_id_event {
83 struct perf_event_header header;
84 pid_t pid;
85 uint8_t build_id[24];
86 char filename[header.size - offsetof(struct build_id_event, filename)];
87};
88
89 HEADER_HOSTNAME = 3,
90
91A perf_header_string with the hostname where the data was collected
92(uname -n)
93
94 HEADER_OSRELEASE = 4,
95
96A perf_header_string with the os release where the data was collected
97(uname -r)
98
99 HEADER_VERSION = 5,
100
101A perf_header_string with the perf user tool version where the
102data was collected. This is the same as the version of the source tree
103the perf tool was built from.
104
105 HEADER_ARCH = 6,
106
107A perf_header_string with the CPU architecture (uname -m)
108
109 HEADER_NRCPUS = 7,
110
111A structure defining the number of CPUs.
112
113struct nr_cpus {
114 uint32_t nr_cpus_online;
115 uint32_t nr_cpus_available; /* CPUs not yet onlined */
116};
117
118 HEADER_CPUDESC = 8,
119
120A perf_header_string with description of the CPU. On x86 this is the model name
121in /proc/cpuinfo
122
123 HEADER_CPUID = 9,
124
125A perf_header_string with the exact CPU type. On x86 this is
126vendor,family,model,stepping. For example: GenuineIntel,6,69,1
127
128 HEADER_TOTAL_MEM = 10,
129
130An uint64_t with the total memory in bytes.
131
132 HEADER_CMDLINE = 11,
133
134A perf_header_string with the perf command line used to collect the data.
135
136 HEADER_EVENT_DESC = 12,
137
138Another description of the perf_event_attrs, more detailed than header.attrs
139including IDs and names. See perf_event.h or the man page for a description
140of a struct perf_event_attr.
141
142struct {
143 uint32_t nr; /* number of events */
144 uint32_t attr_size; /* size of each perf_event_attr */
145 struct {
146 struct perf_event_attr attr; /* size of attr_size */
147 uint32_t nr_ids;
148 struct perf_header_string event_string;
149 uint64_t ids[nr_ids];
150 } events[nr]; /* Variable length records */
151};
152
153 HEADER_CPU_TOPOLOGY = 13,
154
155String lists defining the core and CPU threads topology.
156
157struct {
158 struct perf_header_string_list cores; /* Variable length */
159 struct perf_header_string_list threads; /* Variable length */
160};
161
162Example:
163 sibling cores : 0-3
164 sibling threads : 0-1
165 sibling threads : 2-3
166
167 HEADER_NUMA_TOPOLOGY = 14,
168
169 A list of NUMA node descriptions
170
171struct {
172 uint32_t nr;
173 struct {
174 uint32_t nodenr;
175 uint64_t mem_total;
176 uint64_t mem_free;
177 struct perf_header_string cpus;
178 } nodes[nr]; /* Variable length records */
179};
180
181 HEADER_BRANCH_STACK = 15,
182
183Not implemented in perf.
184
185 HEADER_PMU_MAPPINGS = 16,
186
187 A list of PMU structures, defining the different PMUs supported by perf.
188
189struct {
190 uint32_t nr;
191 struct pmu {
192 uint32_t pmu_type;
193 struct perf_header_string pmu_name;
194 } [nr]; /* Variable length records */
195};
196
197 HEADER_GROUP_DESC = 17,
198
199 Description of counter groups ({...} in perf syntax)
200
201struct {
202 uint32_t nr;
203 struct {
204 struct perf_header_string string;
205 uint32_t leader_idx;
206 uint32_t nr_members;
207 } [nr]; /* Variable length records */
208};
209
210 HEADER_AUXTRACE = 18,
211
212Define additional auxtrace areas in the perf.data. auxtrace is used to store
213undecoded hardware tracing information, such as Intel Processor Trace data.
214
215/**
216 * struct auxtrace_index_entry - indexes a AUX area tracing event within a
217 * perf.data file.
218 * @file_offset: offset within the perf.data file
219 * @sz: size of the event
220 */
221struct auxtrace_index_entry {
222 u64 file_offset;
223 u64 sz;
224};
225
226#define PERF_AUXTRACE_INDEX_ENTRY_COUNT 256
227
228/**
229 * struct auxtrace_index - index of AUX area tracing events within a perf.data
230 * file.
231 * @list: linking a number of arrays of entries
232 * @nr: number of entries
233 * @entries: array of entries
234 */
235struct auxtrace_index {
236 struct list_head list;
237 size_t nr;
238 struct auxtrace_index_entry entries[PERF_AUXTRACE_INDEX_ENTRY_COUNT];
239};
240
241 other bits are reserved and should ignored for now
242 HEADER_FEAT_BITS = 256,
243
244Attributes
245
246This is an array of perf_event_attrs, each attr_size bytes long, which defines
247each event collected. See perf_event.h or the man page for a detailed
248description.
249
250Data
251
252This section is the bulk of the file. It consist of a stream of perf_events
253describing events. This matches the format generated by the kernel.
254See perf_event.h or the manpage for a detailed description.
255
256Some notes on parsing:
257
258Ordering
259
260The events are not necessarily in time stamp order, as they can be
261collected in parallel on different CPUs. If the events should be
262processed in time order they need to be sorted first. It is possible
263to only do a partial sort using the FINISHED_ROUND event header (see
264below). perf record guarantees that there is no reordering over a
265FINISHED_ROUND.
266
267ID vs IDENTIFIER
268
269When the event stream contains multiple events each event is identified
270by an ID. This can be either through the PERF_SAMPLE_ID or the
271PERF_SAMPLE_IDENTIFIER header. The PERF_SAMPLE_IDENTIFIER header is
272at a fixed offset from the event header, which allows reliable
273parsing of the header. Relying on ID may be ambigious.
274IDENTIFIER is only supported by newer Linux kernels.
275
276Perf record specific events:
277
278In addition to the kernel generated event types perf record adds its
279own event types (in addition it also synthesizes some kernel events,
280for example MMAP events)
281
282 PERF_RECORD_USER_TYPE_START = 64,
283 PERF_RECORD_HEADER_ATTR = 64,
284
285struct attr_event {
286 struct perf_event_header header;
287 struct perf_event_attr attr;
288 uint64_t id[];
289};
290
291 PERF_RECORD_HEADER_EVENT_TYPE = 65, /* depreceated */
292
293#define MAX_EVENT_NAME 64
294
295struct perf_trace_event_type {
296 uint64_t event_id;
297 char name[MAX_EVENT_NAME];
298};
299
300struct event_type_event {
301 struct perf_event_header header;
302 struct perf_trace_event_type event_type;
303};
304
305
306 PERF_RECORD_HEADER_TRACING_DATA = 66,
307
308Describe me
309
310struct tracing_data_event {
311 struct perf_event_header header;
312 uint32_t size;
313};
314
315 PERF_RECORD_HEADER_BUILD_ID = 67,
316
317Define a ELF build ID for a referenced executable.
318
319 struct build_id_event; /* See above */
320
321 PERF_RECORD_FINISHED_ROUND = 68,
322
323No event reordering over this header. No payload.
324
325 PERF_RECORD_ID_INDEX = 69,
326
327Map event ids to CPUs and TIDs.
328
329struct id_index_entry {
330 uint64_t id;
331 uint64_t idx;
332 uint64_t cpu;
333 uint64_t tid;
334};
335
336struct id_index_event {
337 struct perf_event_header header;
338 uint64_t nr;
339 struct id_index_entry entries[nr];
340};
341
342 PERF_RECORD_AUXTRACE_INFO = 70,
343
344Auxtrace type specific information. Describe me
345
346struct auxtrace_info_event {
347 struct perf_event_header header;
348 uint32_t type;
349 uint32_t reserved__; /* For alignment */
350 uint64_t priv[];
351};
352
353 PERF_RECORD_AUXTRACE = 71,
354
355Defines auxtrace data. Followed by the actual data. The contents of
356the auxtrace data is dependent on the event and the CPU. For example
357for Intel Processor Trace it contains Processor Trace data generated
358by the CPU.
359
360struct auxtrace_event {
361 struct perf_event_header header;
362 uint64_t size;
363 uint64_t offset;
364 uint64_t reference;
365 uint32_t idx;
366 uint32_t tid;
367 uint32_t cpu;
368 uint32_t reserved__; /* For alignment */
369};
370
371struct aux_event {
372 struct perf_event_header header;
373 uint64_t aux_offset;
374 uint64_t aux_size;
375 uint64_t flags;
376};
377
378 PERF_RECORD_AUXTRACE_ERROR = 72,
379
380Describes an error in hardware tracing
381
382enum auxtrace_error_type {
383 PERF_AUXTRACE_ERROR_ITRACE = 1,
384 PERF_AUXTRACE_ERROR_MAX
385};
386
387#define MAX_AUXTRACE_ERROR_MSG 64
388
389struct auxtrace_error_event {
390 struct perf_event_header header;
391 uint32_t type;
392 uint32_t code;
393 uint32_t cpu;
394 uint32_t pid;
395 uint32_t tid;
396 uint32_t reserved__; /* For alignment */
397 uint64_t ip;
398 char msg[MAX_AUXTRACE_ERROR_MSG];
399};
400
401Event types
402
403Define the event attributes with their IDs.
404
405An array bound by the perf_file_section size.
406
407 struct {
408 struct perf_event_attr attr; /* Size defined by header.attr_size */
409 struct perf_file_section ids;
410 }
411
412ids points to a array of uint64_t defining the ids for event attr attr.
413
414References:
415
416include/uapi/linux/perf_event.h
417
418This is the canonical description of the kernel generated perf_events
419and the perf_event_attrs.
420
421perf_events manpage
422
423A manpage describing perf_event and perf_event_attr is here:
424http://web.eece.maine.edu/~vweaver/projects/perf_events/programming.html
425This tends to be slightly behind the kernel include, but has better
426descriptions. An (typically older) version of the man page may be
427included with the standard Linux man pages, available with "man
428perf_events"
429
430pmu-tools
431
432https://github.com/andikleen/pmu-tools/tree/master/parser
433
434A definition of the perf.data format in python "construct" format is available
435in pmu-tools parser. This allows to read perf.data from python and dump it.
436
437quipper
438
439The quipper C++ parser is available at
440https://chromium.googlesource.com/chromiumos/platform/chromiumos-wide-profiling/
441Unfortunately this parser tends to be many versions behind and may not be able
442to parse data files generated by recent perf.
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 8c8c6b9ce915..ad2534df4ba6 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -12,13 +12,23 @@ tools/arch/sparc/include/asm/barrier_32.h
12tools/arch/sparc/include/asm/barrier_64.h 12tools/arch/sparc/include/asm/barrier_64.h
13tools/arch/tile/include/asm/barrier.h 13tools/arch/tile/include/asm/barrier.h
14tools/arch/x86/include/asm/barrier.h 14tools/arch/x86/include/asm/barrier.h
15tools/arch/x86/include/asm/cpufeatures.h
16tools/arch/x86/include/asm/disabled-features.h
17tools/arch/x86/include/asm/required-features.h
18tools/arch/x86/include/uapi/asm/svm.h
19tools/arch/x86/include/uapi/asm/vmx.h
20tools/arch/x86/include/uapi/asm/kvm.h
21tools/arch/x86/include/uapi/asm/kvm_perf.h
22tools/arch/x86/lib/memcpy_64.S
23tools/arch/x86/lib/memset_64.S
24tools/arch/s390/include/uapi/asm/kvm_perf.h
25tools/arch/s390/include/uapi/asm/sie.h
15tools/arch/xtensa/include/asm/barrier.h 26tools/arch/xtensa/include/asm/barrier.h
16tools/scripts 27tools/scripts
17tools/build 28tools/build
18tools/arch/x86/include/asm/atomic.h 29tools/arch/x86/include/asm/atomic.h
19tools/arch/x86/include/asm/rmwcc.h 30tools/arch/x86/include/asm/rmwcc.h
20tools/lib/traceevent 31tools/lib/traceevent
21tools/lib/bpf
22tools/lib/api 32tools/lib/api
23tools/lib/bpf 33tools/lib/bpf
24tools/lib/subcmd 34tools/lib/subcmd
@@ -29,6 +39,9 @@ tools/lib/symbol/kallsyms.c
29tools/lib/symbol/kallsyms.h 39tools/lib/symbol/kallsyms.h
30tools/lib/find_bit.c 40tools/lib/find_bit.c
31tools/lib/bitmap.c 41tools/lib/bitmap.c
42tools/lib/str_error_r.c
43tools/lib/vsprintf.c
44tools/include/asm/alternative-asm.h
32tools/include/asm/atomic.h 45tools/include/asm/atomic.h
33tools/include/asm/barrier.h 46tools/include/asm/barrier.h
34tools/include/asm/bug.h 47tools/include/asm/bug.h
@@ -52,43 +65,16 @@ tools/include/linux/hash.h
52tools/include/linux/kernel.h 65tools/include/linux/kernel.h
53tools/include/linux/list.h 66tools/include/linux/list.h
54tools/include/linux/log2.h 67tools/include/linux/log2.h
68tools/include/uapi/linux/bpf.h
69tools/include/uapi/linux/bpf_common.h
70tools/include/uapi/linux/hw_breakpoint.h
71tools/include/uapi/linux/perf_event.h
55tools/include/linux/poison.h 72tools/include/linux/poison.h
56tools/include/linux/rbtree.h 73tools/include/linux/rbtree.h
57tools/include/linux/rbtree_augmented.h 74tools/include/linux/rbtree_augmented.h
58tools/include/linux/string.h 75tools/include/linux/string.h
76tools/include/linux/stringify.h
59tools/include/linux/types.h 77tools/include/linux/types.h
60tools/include/linux/err.h 78tools/include/linux/err.h
61tools/include/linux/bitmap.h 79tools/include/linux/bitmap.h
62include/asm-generic/bitops/arch_hweight.h 80tools/arch/*/include/uapi/asm/perf_regs.h
63include/asm-generic/bitops/const_hweight.h
64include/asm-generic/bitops/fls64.h
65include/asm-generic/bitops/__fls.h
66include/asm-generic/bitops/fls.h
67include/linux/perf_event.h
68include/linux/list.h
69include/linux/hash.h
70include/linux/stringify.h
71include/linux/swab.h
72arch/*/include/asm/unistd*.h
73arch/*/include/uapi/asm/unistd*.h
74arch/*/include/uapi/asm/perf_regs.h
75arch/*/lib/memcpy*.S
76arch/*/lib/memset*.S
77arch/*/include/asm/*features.h
78include/linux/poison.h
79include/linux/hw_breakpoint.h
80include/uapi/linux/perf_event.h
81include/uapi/linux/bpf.h
82include/uapi/linux/bpf_common.h
83include/uapi/linux/const.h
84include/uapi/linux/swab.h
85include/uapi/linux/hw_breakpoint.h
86arch/x86/include/asm/svm.h
87arch/x86/include/asm/vmx.h
88arch/x86/include/asm/kvm_host.h
89arch/x86/include/uapi/asm/svm.h
90arch/x86/include/uapi/asm/vmx.h
91arch/x86/include/uapi/asm/kvm.h
92arch/x86/include/uapi/asm/kvm_perf.h
93arch/s390/include/uapi/asm/sie.h
94arch/s390/include/uapi/asm/kvm_perf.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index bde8cbae7dd9..6641abb97f0a 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -81,6 +81,9 @@ include ../scripts/utilities.mak
81# 81#
82# Define NO_LIBBPF if you do not want BPF support 82# Define NO_LIBBPF if you do not want BPF support
83# 83#
84# Define NO_SDT if you do not want to define SDT event in perf tools,
85# note that it doesn't disable SDT scanning support.
86#
84# Define FEATURES_DUMP to provide features detection dump file 87# Define FEATURES_DUMP to provide features detection dump file
85# and bypass the feature detection 88# and bypass the feature detection
86 89
@@ -254,7 +257,8 @@ PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
254PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI) 257PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI)
255 258
256$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) 259$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST)
257 $(QUIET_GEN)CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \ 260 $(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \
261 CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \
258 $(PYTHON_WORD) util/setup.py \ 262 $(PYTHON_WORD) util/setup.py \
259 --quiet build_ext; \ 263 --quiet build_ext; \
260 mkdir -p $(OUTPUT)python && \ 264 mkdir -p $(OUTPUT)python && \
@@ -344,6 +348,87 @@ export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
344include $(srctree)/tools/build/Makefile.include 348include $(srctree)/tools/build/Makefile.include
345 349
346$(PERF_IN): prepare FORCE 350$(PERF_IN): prepare FORCE
351 @(test -f ../../include/uapi/linux/perf_event.h && ( \
352 (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \
353 || echo "Warning: tools/include/uapi/linux/perf_event.h differs from kernel" >&2 )) || true
354 @(test -f ../../include/linux/hash.h && ( \
355 (diff -B ../include/linux/hash.h ../../include/linux/hash.h >/dev/null) \
356 || echo "Warning: tools/include/linux/hash.h differs from kernel" >&2 )) || true
357 @(test -f ../../include/uapi/linux/hw_breakpoint.h && ( \
358 (diff -B ../include/uapi/linux/hw_breakpoint.h ../../include/uapi/linux/hw_breakpoint.h >/dev/null) \
359 || echo "Warning: tools/include/uapi/linux/hw_breakpoint.h differs from kernel" >&2 )) || true
360 @(test -f ../../arch/x86/include/asm/disabled-features.h && ( \
361 (diff -B ../arch/x86/include/asm/disabled-features.h ../../arch/x86/include/asm/disabled-features.h >/dev/null) \
362 || echo "Warning: tools/arch/x86/include/asm/disabled-features.h differs from kernel" >&2 )) || true
363 @(test -f ../../arch/x86/include/asm/required-features.h && ( \
364 (diff -B ../arch/x86/include/asm/required-features.h ../../arch/x86/include/asm/required-features.h >/dev/null) \
365 || echo "Warning: tools/arch/x86/include/asm/required-features.h differs from kernel" >&2 )) || true
366 @(test -f ../../arch/x86/include/asm/cpufeatures.h && ( \
367 (diff -B ../arch/x86/include/asm/cpufeatures.h ../../arch/x86/include/asm/cpufeatures.h >/dev/null) \
368 || echo "Warning: tools/arch/x86/include/asm/cpufeatures.h differs from kernel" >&2 )) || true
369 @(test -f ../../arch/x86/lib/memcpy_64.S && ( \
370 (diff -B ../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memcpy_64.S >/dev/null) \
371 || echo "Warning: tools/arch/x86/lib/memcpy_64.S differs from kernel" >&2 )) || true
372 @(test -f ../../arch/x86/lib/memset_64.S && ( \
373 (diff -B ../arch/x86/lib/memset_64.S ../../arch/x86/lib/memset_64.S >/dev/null) \
374 || echo "Warning: tools/arch/x86/lib/memset_64.S differs from kernel" >&2 )) || true
375 @(test -f ../../arch/arm/include/uapi/asm/perf_regs.h && ( \
376 (diff -B ../arch/arm/include/uapi/asm/perf_regs.h ../../arch/arm/include/uapi/asm/perf_regs.h >/dev/null) \
377 || echo "Warning: tools/arch/arm/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
378 @(test -f ../../arch/arm64/include/uapi/asm/perf_regs.h && ( \
379 (diff -B ../arch/arm64/include/uapi/asm/perf_regs.h ../../arch/arm64/include/uapi/asm/perf_regs.h >/dev/null) \
380 || echo "Warning: tools/arch/arm64/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
381 @(test -f ../../arch/powerpc/include/uapi/asm/perf_regs.h && ( \
382 (diff -B ../arch/powerpc/include/uapi/asm/perf_regs.h ../../arch/powerpc/include/uapi/asm/perf_regs.h >/dev/null) \
383 || echo "Warning: tools/arch/powerpc/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
384 @(test -f ../../arch/x86/include/uapi/asm/perf_regs.h && ( \
385 (diff -B ../arch/x86/include/uapi/asm/perf_regs.h ../../arch/x86/include/uapi/asm/perf_regs.h >/dev/null) \
386 || echo "Warning: tools/arch/x86/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true
387 @(test -f ../../arch/x86/include/uapi/asm/kvm.h && ( \
388 (diff -B ../arch/x86/include/uapi/asm/kvm.h ../../arch/x86/include/uapi/asm/kvm.h >/dev/null) \
389 || echo "Warning: tools/arch/x86/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
390 @(test -f ../../arch/x86/include/uapi/asm/kvm_perf.h && ( \
391 (diff -B ../arch/x86/include/uapi/asm/kvm_perf.h ../../arch/x86/include/uapi/asm/kvm_perf.h >/dev/null) \
392 || echo "Warning: tools/arch/x86/include/uapi/asm/kvm_perf.h differs from kernel" >&2 )) || true
393 @(test -f ../../arch/x86/include/uapi/asm/svm.h && ( \
394 (diff -B ../arch/x86/include/uapi/asm/svm.h ../../arch/x86/include/uapi/asm/svm.h >/dev/null) \
395 || echo "Warning: tools/arch/x86/include/uapi/asm/svm.h differs from kernel" >&2 )) || true
396 @(test -f ../../arch/x86/include/uapi/asm/vmx.h && ( \
397 (diff -B ../arch/x86/include/uapi/asm/vmx.h ../../arch/x86/include/uapi/asm/vmx.h >/dev/null) \
398 || echo "Warning: tools/arch/x86/include/uapi/asm/vmx.h differs from kernel" >&2 )) || true
399 @(test -f ../../arch/powerpc/include/uapi/asm/kvm.h && ( \
400 (diff -B ../arch/powerpc/include/uapi/asm/kvm.h ../../arch/powerpc/include/uapi/asm/kvm.h >/dev/null) \
401 || echo "Warning: tools/arch/powerpc/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
402 @(test -f ../../arch/s390/include/uapi/asm/kvm.h && ( \
403 (diff -B ../arch/s390/include/uapi/asm/kvm.h ../../arch/s390/include/uapi/asm/kvm.h >/dev/null) \
404 || echo "Warning: tools/arch/s390/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
405 @(test -f ../../arch/s390/include/uapi/asm/kvm_perf.h && ( \
406 (diff -B ../arch/s390/include/uapi/asm/kvm_perf.h ../../arch/s390/include/uapi/asm/kvm_perf.h >/dev/null) \
407 || echo "Warning: tools/arch/s390/include/uapi/asm/kvm_perf.h differs from kernel" >&2 )) || true
408 @(test -f ../../arch/s390/include/uapi/asm/sie.h && ( \
409 (diff -B ../arch/s390/include/uapi/asm/sie.h ../../arch/s390/include/uapi/asm/sie.h >/dev/null) \
410 || echo "Warning: tools/arch/s390/include/uapi/asm/sie.h differs from kernel" >&2 )) || true
411 @(test -f ../../arch/arm/include/uapi/asm/kvm.h && ( \
412 (diff -B ../arch/arm/include/uapi/asm/kvm.h ../../arch/arm/include/uapi/asm/kvm.h >/dev/null) \
413 || echo "Warning: tools/arch/arm/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
414 @(test -f ../../arch/arm64/include/uapi/asm/kvm.h && ( \
415 (diff -B ../arch/arm64/include/uapi/asm/kvm.h ../../arch/arm64/include/uapi/asm/kvm.h >/dev/null) \
416 || echo "Warning: tools/arch/arm64/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
417 @(test -f ../../include/asm-generic/bitops/arch_hweight.h && ( \
418 (diff -B ../include/asm-generic/bitops/arch_hweight.h ../../include/asm-generic/bitops/arch_hweight.h >/dev/null) \
419 || echo "Warning: tools/include/asm-generic/bitops/arch_hweight.h differs from kernel" >&2 )) || true
420 @(test -f ../../include/asm-generic/bitops/const_hweight.h && ( \
421 (diff -B ../include/asm-generic/bitops/const_hweight.h ../../include/asm-generic/bitops/const_hweight.h >/dev/null) \
422 || echo "Warning: tools/include/asm-generic/bitops/const_hweight.h differs from kernel" >&2 )) || true
423 @(test -f ../../include/asm-generic/bitops/__fls.h && ( \
424 (diff -B ../include/asm-generic/bitops/__fls.h ../../include/asm-generic/bitops/__fls.h >/dev/null) \
425 || echo "Warning: tools/include/asm-generic/bitops/__fls.h differs from kernel" >&2 )) || true
426 @(test -f ../../include/asm-generic/bitops/fls.h && ( \
427 (diff -B ../include/asm-generic/bitops/fls.h ../../include/asm-generic/bitops/fls.h >/dev/null) \
428 || echo "Warning: tools/include/asm-generic/bitops/fls.h differs from kernel" >&2 )) || true
429 @(test -f ../../include/asm-generic/bitops/fls64.h && ( \
430 (diff -B ../include/asm-generic/bitops/fls64.h ../../include/asm-generic/bitops/fls64.h >/dev/null) \
431 || echo "Warning: tools/include/asm-generic/bitops/fls64.h differs from kernel" >&2 )) || true
347 $(Q)$(MAKE) $(build)=perf 432 $(Q)$(MAKE) $(build)=perf
348 433
349$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) 434$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build
index d22e3d07de3d..f98da17357c0 100644
--- a/tools/perf/arch/arm/util/Build
+++ b/tools/perf/arch/arm/util/Build
@@ -1,4 +1,4 @@
1libperf-$(CONFIG_DWARF) += dwarf-regs.o 1libperf-$(CONFIG_DWARF) += dwarf-regs.o
2 2
3libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o 3libperf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
4libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o 4libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
index e58123a8912b..02f41dba4f4f 100644
--- a/tools/perf/arch/arm64/util/Build
+++ b/tools/perf/arch/arm64/util/Build
@@ -1,2 +1,2 @@
1libperf-$(CONFIG_DWARF) += dwarf-regs.o 1libperf-$(CONFIG_DWARF) += dwarf-regs.o
2libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o 2libperf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
diff --git a/tools/perf/arch/arm64/util/unwind-libunwind.c b/tools/perf/arch/arm64/util/unwind-libunwind.c
index a87afa91a99e..c116b713f7f7 100644
--- a/tools/perf/arch/arm64/util/unwind-libunwind.c
+++ b/tools/perf/arch/arm64/util/unwind-libunwind.c
@@ -1,11 +1,13 @@
1 1
2#ifndef REMOTE_UNWIND_LIBUNWIND
2#include <errno.h> 3#include <errno.h>
3#include <libunwind.h> 4#include <libunwind.h>
4#include "perf_regs.h" 5#include "perf_regs.h"
5#include "../../util/unwind.h" 6#include "../../util/unwind.h"
6#include "../../util/debug.h" 7#include "../../util/debug.h"
8#endif
7 9
8int libunwind__arch_reg_id(int regnum) 10int LIBUNWIND__ARCH_REG_ID(int regnum)
9{ 11{
10 switch (regnum) { 12 switch (regnum) {
11 case UNW_AARCH64_X0: 13 case UNW_AARCH64_X0:
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index e83c8ce24303..886dd2aaff0d 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -1,6 +1,7 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <sys/utsname.h> 2#include <sys/utsname.h>
3#include "common.h" 3#include "common.h"
4#include "../util/util.h"
4#include "../util/debug.h" 5#include "../util/debug.h"
5 6
6const char *const arm_triplets[] = { 7const char *const arm_triplets[] = {
@@ -9,34 +10,44 @@ const char *const arm_triplets[] = {
9 "arm-unknown-linux-", 10 "arm-unknown-linux-",
10 "arm-unknown-linux-gnu-", 11 "arm-unknown-linux-gnu-",
11 "arm-unknown-linux-gnueabi-", 12 "arm-unknown-linux-gnueabi-",
13 "arm-linux-gnu-",
14 "arm-linux-gnueabihf-",
15 "arm-none-eabi-",
12 NULL 16 NULL
13}; 17};
14 18
15const char *const arm64_triplets[] = { 19const char *const arm64_triplets[] = {
16 "aarch64-linux-android-", 20 "aarch64-linux-android-",
21 "aarch64-linux-gnu-",
17 NULL 22 NULL
18}; 23};
19 24
20const char *const powerpc_triplets[] = { 25const char *const powerpc_triplets[] = {
21 "powerpc-unknown-linux-gnu-", 26 "powerpc-unknown-linux-gnu-",
22 "powerpc64-unknown-linux-gnu-", 27 "powerpc64-unknown-linux-gnu-",
28 "powerpc64-linux-gnu-",
29 "powerpc64le-linux-gnu-",
23 NULL 30 NULL
24}; 31};
25 32
26const char *const s390_triplets[] = { 33const char *const s390_triplets[] = {
27 "s390-ibm-linux-", 34 "s390-ibm-linux-",
35 "s390x-linux-gnu-",
28 NULL 36 NULL
29}; 37};
30 38
31const char *const sh_triplets[] = { 39const char *const sh_triplets[] = {
32 "sh-unknown-linux-gnu-", 40 "sh-unknown-linux-gnu-",
33 "sh64-unknown-linux-gnu-", 41 "sh64-unknown-linux-gnu-",
42 "sh-linux-gnu-",
43 "sh64-linux-gnu-",
34 NULL 44 NULL
35}; 45};
36 46
37const char *const sparc_triplets[] = { 47const char *const sparc_triplets[] = {
38 "sparc-unknown-linux-gnu-", 48 "sparc-unknown-linux-gnu-",
39 "sparc64-unknown-linux-gnu-", 49 "sparc64-unknown-linux-gnu-",
50 "sparc64-linux-gnu-",
40 NULL 51 NULL
41}; 52};
42 53
@@ -49,12 +60,19 @@ const char *const x86_triplets[] = {
49 "i386-pc-linux-gnu-", 60 "i386-pc-linux-gnu-",
50 "i686-linux-android-", 61 "i686-linux-android-",
51 "i686-android-linux-", 62 "i686-android-linux-",
63 "x86_64-linux-gnu-",
64 "i586-linux-gnu-",
52 NULL 65 NULL
53}; 66};
54 67
55const char *const mips_triplets[] = { 68const char *const mips_triplets[] = {
56 "mips-unknown-linux-gnu-", 69 "mips-unknown-linux-gnu-",
57 "mipsel-linux-android-", 70 "mipsel-linux-android-",
71 "mips-linux-gnu-",
72 "mips64-linux-gnu-",
73 "mips64el-linux-gnuabi64-",
74 "mips64-linux-gnuabi64-",
75 "mipsel-linux-gnu-",
58 NULL 76 NULL
59}; 77};
60 78
@@ -102,7 +120,7 @@ static int lookup_triplets(const char *const *triplets, const char *name)
102 * Return architecture name in a normalized form. 120 * Return architecture name in a normalized form.
103 * The conversion logic comes from the Makefile. 121 * The conversion logic comes from the Makefile.
104 */ 122 */
105static const char *normalize_arch(char *arch) 123const char *normalize_arch(char *arch)
106{ 124{
107 if (!strcmp(arch, "x86_64")) 125 if (!strcmp(arch, "x86_64"))
108 return "x86"; 126 return "x86";
diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h
index 7529cfb143ce..6b01c736b7d9 100644
--- a/tools/perf/arch/common.h
+++ b/tools/perf/arch/common.h
@@ -6,5 +6,6 @@
6extern const char *objdump_path; 6extern const char *objdump_path;
7 7
8int perf_env__lookup_objdump(struct perf_env *env); 8int perf_env__lookup_objdump(struct perf_env *env);
9const char *normalize_arch(char *arch);
9 10
10#endif /* ARCH_PERF_COMMON_H */ 11#endif /* ARCH_PERF_COMMON_H */
diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build
index 8a61372bb47a..5bd7b9260cc0 100644
--- a/tools/perf/arch/s390/util/Build
+++ b/tools/perf/arch/s390/util/Build
@@ -2,3 +2,5 @@ libperf-y += header.o
2libperf-y += kvm-stat.o 2libperf-y += kvm-stat.o
3 3
4libperf-$(CONFIG_DWARF) += dwarf-regs.o 4libperf-$(CONFIG_DWARF) += dwarf-regs.o
5
6libperf-y += machine.o
diff --git a/tools/perf/arch/s390/util/machine.c b/tools/perf/arch/s390/util/machine.c
new file mode 100644
index 000000000000..b9a95a1a8e69
--- /dev/null
+++ b/tools/perf/arch/s390/util/machine.c
@@ -0,0 +1,19 @@
1#include <unistd.h>
2#include <stdio.h>
3#include <string.h>
4#include "util.h"
5#include "machine.h"
6#include "api/fs/fs.h"
7
8int arch__fix_module_text_start(u64 *start, const char *name)
9{
10 char path[PATH_MAX];
11
12 snprintf(path, PATH_MAX, "module/%.*s/sections/.text",
13 (int)strlen(name) - 2, name + 1);
14
15 if (sysfs__read_ull(path, (unsigned long long *)start) < 0)
16 return -1;
17
18 return 0;
19}
diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
index cac6d17ce5db..555263e385c9 100644
--- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
@@ -374,3 +374,5 @@
374543 x32 io_setup compat_sys_io_setup 374543 x32 io_setup compat_sys_io_setup
375544 x32 io_submit compat_sys_io_submit 375544 x32 io_submit compat_sys_io_submit
376545 x32 execveat compat_sys_execveat/ptregs 376545 x32 execveat compat_sys_execveat/ptregs
377534 x32 preadv2 compat_sys_preadv2
378535 x32 pwritev2 compat_sys_pwritev2
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-32.c b/tools/perf/arch/x86/tests/insn-x86-dat-32.c
index 3b491cfe204e..0f196eec9f48 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-32.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-32.c
@@ -6,6 +6,1016 @@
6 6
7{{0x0f, 0x31, }, 2, 0, "", "", 7{{0x0f, 0x31, }, 2, 0, "", "",
8"0f 31 \trdtsc ",}, 8"0f 31 \trdtsc ",},
9{{0xc4, 0xe2, 0x7d, 0x13, 0xeb, }, 5, 0, "", "",
10"c4 e2 7d 13 eb \tvcvtph2ps %xmm3,%ymm5",},
11{{0x62, 0x81, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
12"62 81 78 56 34 12 \tbound %eax,0x12345678(%ecx)",},
13{{0x62, 0x88, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
14"62 88 78 56 34 12 \tbound %ecx,0x12345678(%eax)",},
15{{0x62, 0x90, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
16"62 90 78 56 34 12 \tbound %edx,0x12345678(%eax)",},
17{{0x62, 0x98, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
18"62 98 78 56 34 12 \tbound %ebx,0x12345678(%eax)",},
19{{0x62, 0xa0, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
20"62 a0 78 56 34 12 \tbound %esp,0x12345678(%eax)",},
21{{0x62, 0xa8, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
22"62 a8 78 56 34 12 \tbound %ebp,0x12345678(%eax)",},
23{{0x62, 0xb0, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
24"62 b0 78 56 34 12 \tbound %esi,0x12345678(%eax)",},
25{{0x62, 0xb8, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
26"62 b8 78 56 34 12 \tbound %edi,0x12345678(%eax)",},
27{{0x62, 0x08, }, 2, 0, "", "",
28"62 08 \tbound %ecx,(%eax)",},
29{{0x62, 0x05, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
30"62 05 78 56 34 12 \tbound %eax,0x12345678",},
31{{0x62, 0x14, 0x01, }, 3, 0, "", "",
32"62 14 01 \tbound %edx,(%ecx,%eax,1)",},
33{{0x62, 0x14, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
34"62 14 05 78 56 34 12 \tbound %edx,0x12345678(,%eax,1)",},
35{{0x62, 0x14, 0x08, }, 3, 0, "", "",
36"62 14 08 \tbound %edx,(%eax,%ecx,1)",},
37{{0x62, 0x14, 0xc8, }, 3, 0, "", "",
38"62 14 c8 \tbound %edx,(%eax,%ecx,8)",},
39{{0x62, 0x50, 0x12, }, 3, 0, "", "",
40"62 50 12 \tbound %edx,0x12(%eax)",},
41{{0x62, 0x55, 0x12, }, 3, 0, "", "",
42"62 55 12 \tbound %edx,0x12(%ebp)",},
43{{0x62, 0x54, 0x01, 0x12, }, 4, 0, "", "",
44"62 54 01 12 \tbound %edx,0x12(%ecx,%eax,1)",},
45{{0x62, 0x54, 0x05, 0x12, }, 4, 0, "", "",
46"62 54 05 12 \tbound %edx,0x12(%ebp,%eax,1)",},
47{{0x62, 0x54, 0x08, 0x12, }, 4, 0, "", "",
48"62 54 08 12 \tbound %edx,0x12(%eax,%ecx,1)",},
49{{0x62, 0x54, 0xc8, 0x12, }, 4, 0, "", "",
50"62 54 c8 12 \tbound %edx,0x12(%eax,%ecx,8)",},
51{{0x62, 0x90, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
52"62 90 78 56 34 12 \tbound %edx,0x12345678(%eax)",},
53{{0x62, 0x95, 0x78, 0x56, 0x34, 0x12, }, 6, 0, "", "",
54"62 95 78 56 34 12 \tbound %edx,0x12345678(%ebp)",},
55{{0x62, 0x94, 0x01, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
56"62 94 01 78 56 34 12 \tbound %edx,0x12345678(%ecx,%eax,1)",},
57{{0x62, 0x94, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
58"62 94 05 78 56 34 12 \tbound %edx,0x12345678(%ebp,%eax,1)",},
59{{0x62, 0x94, 0x08, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
60"62 94 08 78 56 34 12 \tbound %edx,0x12345678(%eax,%ecx,1)",},
61{{0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
62"62 94 c8 78 56 34 12 \tbound %edx,0x12345678(%eax,%ecx,8)",},
63{{0x66, 0x62, 0x81, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
64"66 62 81 78 56 34 12 \tbound %ax,0x12345678(%ecx)",},
65{{0x66, 0x62, 0x88, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
66"66 62 88 78 56 34 12 \tbound %cx,0x12345678(%eax)",},
67{{0x66, 0x62, 0x90, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
68"66 62 90 78 56 34 12 \tbound %dx,0x12345678(%eax)",},
69{{0x66, 0x62, 0x98, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
70"66 62 98 78 56 34 12 \tbound %bx,0x12345678(%eax)",},
71{{0x66, 0x62, 0xa0, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
72"66 62 a0 78 56 34 12 \tbound %sp,0x12345678(%eax)",},
73{{0x66, 0x62, 0xa8, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
74"66 62 a8 78 56 34 12 \tbound %bp,0x12345678(%eax)",},
75{{0x66, 0x62, 0xb0, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
76"66 62 b0 78 56 34 12 \tbound %si,0x12345678(%eax)",},
77{{0x66, 0x62, 0xb8, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
78"66 62 b8 78 56 34 12 \tbound %di,0x12345678(%eax)",},
79{{0x66, 0x62, 0x08, }, 3, 0, "", "",
80"66 62 08 \tbound %cx,(%eax)",},
81{{0x66, 0x62, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
82"66 62 05 78 56 34 12 \tbound %ax,0x12345678",},
83{{0x66, 0x62, 0x14, 0x01, }, 4, 0, "", "",
84"66 62 14 01 \tbound %dx,(%ecx,%eax,1)",},
85{{0x66, 0x62, 0x14, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
86"66 62 14 05 78 56 34 12 \tbound %dx,0x12345678(,%eax,1)",},
87{{0x66, 0x62, 0x14, 0x08, }, 4, 0, "", "",
88"66 62 14 08 \tbound %dx,(%eax,%ecx,1)",},
89{{0x66, 0x62, 0x14, 0xc8, }, 4, 0, "", "",
90"66 62 14 c8 \tbound %dx,(%eax,%ecx,8)",},
91{{0x66, 0x62, 0x50, 0x12, }, 4, 0, "", "",
92"66 62 50 12 \tbound %dx,0x12(%eax)",},
93{{0x66, 0x62, 0x55, 0x12, }, 4, 0, "", "",
94"66 62 55 12 \tbound %dx,0x12(%ebp)",},
95{{0x66, 0x62, 0x54, 0x01, 0x12, }, 5, 0, "", "",
96"66 62 54 01 12 \tbound %dx,0x12(%ecx,%eax,1)",},
97{{0x66, 0x62, 0x54, 0x05, 0x12, }, 5, 0, "", "",
98"66 62 54 05 12 \tbound %dx,0x12(%ebp,%eax,1)",},
99{{0x66, 0x62, 0x54, 0x08, 0x12, }, 5, 0, "", "",
100"66 62 54 08 12 \tbound %dx,0x12(%eax,%ecx,1)",},
101{{0x66, 0x62, 0x54, 0xc8, 0x12, }, 5, 0, "", "",
102"66 62 54 c8 12 \tbound %dx,0x12(%eax,%ecx,8)",},
103{{0x66, 0x62, 0x90, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
104"66 62 90 78 56 34 12 \tbound %dx,0x12345678(%eax)",},
105{{0x66, 0x62, 0x95, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
106"66 62 95 78 56 34 12 \tbound %dx,0x12345678(%ebp)",},
107{{0x66, 0x62, 0x94, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
108"66 62 94 01 78 56 34 12 \tbound %dx,0x12345678(%ecx,%eax,1)",},
109{{0x66, 0x62, 0x94, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
110"66 62 94 05 78 56 34 12 \tbound %dx,0x12345678(%ebp,%eax,1)",},
111{{0x66, 0x62, 0x94, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
112"66 62 94 08 78 56 34 12 \tbound %dx,0x12345678(%eax,%ecx,1)",},
113{{0x66, 0x62, 0x94, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
114"66 62 94 c8 78 56 34 12 \tbound %dx,0x12345678(%eax,%ecx,8)",},
115{{0x0f, 0x41, 0xd8, }, 3, 0, "", "",
116"0f 41 d8 \tcmovno %eax,%ebx",},
117{{0x0f, 0x41, 0x88, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
118"0f 41 88 78 56 34 12 \tcmovno 0x12345678(%eax),%ecx",},
119{{0x66, 0x0f, 0x41, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
120"66 0f 41 88 78 56 34 12 \tcmovno 0x12345678(%eax),%cx",},
121{{0x0f, 0x44, 0xd8, }, 3, 0, "", "",
122"0f 44 d8 \tcmove %eax,%ebx",},
123{{0x0f, 0x44, 0x88, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
124"0f 44 88 78 56 34 12 \tcmove 0x12345678(%eax),%ecx",},
125{{0x66, 0x0f, 0x44, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
126"66 0f 44 88 78 56 34 12 \tcmove 0x12345678(%eax),%cx",},
127{{0x0f, 0x90, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
128"0f 90 80 78 56 34 12 \tseto 0x12345678(%eax)",},
129{{0x0f, 0x91, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
130"0f 91 80 78 56 34 12 \tsetno 0x12345678(%eax)",},
131{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
132"0f 92 80 78 56 34 12 \tsetb 0x12345678(%eax)",},
133{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
134"0f 92 80 78 56 34 12 \tsetb 0x12345678(%eax)",},
135{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
136"0f 92 80 78 56 34 12 \tsetb 0x12345678(%eax)",},
137{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
138"0f 93 80 78 56 34 12 \tsetae 0x12345678(%eax)",},
139{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
140"0f 93 80 78 56 34 12 \tsetae 0x12345678(%eax)",},
141{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
142"0f 93 80 78 56 34 12 \tsetae 0x12345678(%eax)",},
143{{0x0f, 0x98, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
144"0f 98 80 78 56 34 12 \tsets 0x12345678(%eax)",},
145{{0x0f, 0x99, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
146"0f 99 80 78 56 34 12 \tsetns 0x12345678(%eax)",},
147{{0xc5, 0xcc, 0x41, 0xef, }, 4, 0, "", "",
148"c5 cc 41 ef \tkandw %k7,%k6,%k5",},
149{{0xc4, 0xe1, 0xcc, 0x41, 0xef, }, 5, 0, "", "",
150"c4 e1 cc 41 ef \tkandq %k7,%k6,%k5",},
151{{0xc5, 0xcd, 0x41, 0xef, }, 4, 0, "", "",
152"c5 cd 41 ef \tkandb %k7,%k6,%k5",},
153{{0xc4, 0xe1, 0xcd, 0x41, 0xef, }, 5, 0, "", "",
154"c4 e1 cd 41 ef \tkandd %k7,%k6,%k5",},
155{{0xc5, 0xcc, 0x42, 0xef, }, 4, 0, "", "",
156"c5 cc 42 ef \tkandnw %k7,%k6,%k5",},
157{{0xc4, 0xe1, 0xcc, 0x42, 0xef, }, 5, 0, "", "",
158"c4 e1 cc 42 ef \tkandnq %k7,%k6,%k5",},
159{{0xc5, 0xcd, 0x42, 0xef, }, 4, 0, "", "",
160"c5 cd 42 ef \tkandnb %k7,%k6,%k5",},
161{{0xc4, 0xe1, 0xcd, 0x42, 0xef, }, 5, 0, "", "",
162"c4 e1 cd 42 ef \tkandnd %k7,%k6,%k5",},
163{{0xc5, 0xf8, 0x44, 0xf7, }, 4, 0, "", "",
164"c5 f8 44 f7 \tknotw %k7,%k6",},
165{{0xc4, 0xe1, 0xf8, 0x44, 0xf7, }, 5, 0, "", "",
166"c4 e1 f8 44 f7 \tknotq %k7,%k6",},
167{{0xc5, 0xf9, 0x44, 0xf7, }, 4, 0, "", "",
168"c5 f9 44 f7 \tknotb %k7,%k6",},
169{{0xc4, 0xe1, 0xf9, 0x44, 0xf7, }, 5, 0, "", "",
170"c4 e1 f9 44 f7 \tknotd %k7,%k6",},
171{{0xc5, 0xcc, 0x45, 0xef, }, 4, 0, "", "",
172"c5 cc 45 ef \tkorw %k7,%k6,%k5",},
173{{0xc4, 0xe1, 0xcc, 0x45, 0xef, }, 5, 0, "", "",
174"c4 e1 cc 45 ef \tkorq %k7,%k6,%k5",},
175{{0xc5, 0xcd, 0x45, 0xef, }, 4, 0, "", "",
176"c5 cd 45 ef \tkorb %k7,%k6,%k5",},
177{{0xc4, 0xe1, 0xcd, 0x45, 0xef, }, 5, 0, "", "",
178"c4 e1 cd 45 ef \tkord %k7,%k6,%k5",},
179{{0xc5, 0xcc, 0x46, 0xef, }, 4, 0, "", "",
180"c5 cc 46 ef \tkxnorw %k7,%k6,%k5",},
181{{0xc4, 0xe1, 0xcc, 0x46, 0xef, }, 5, 0, "", "",
182"c4 e1 cc 46 ef \tkxnorq %k7,%k6,%k5",},
183{{0xc5, 0xcd, 0x46, 0xef, }, 4, 0, "", "",
184"c5 cd 46 ef \tkxnorb %k7,%k6,%k5",},
185{{0xc4, 0xe1, 0xcd, 0x46, 0xef, }, 5, 0, "", "",
186"c4 e1 cd 46 ef \tkxnord %k7,%k6,%k5",},
187{{0xc5, 0xcc, 0x47, 0xef, }, 4, 0, "", "",
188"c5 cc 47 ef \tkxorw %k7,%k6,%k5",},
189{{0xc4, 0xe1, 0xcc, 0x47, 0xef, }, 5, 0, "", "",
190"c4 e1 cc 47 ef \tkxorq %k7,%k6,%k5",},
191{{0xc5, 0xcd, 0x47, 0xef, }, 4, 0, "", "",
192"c5 cd 47 ef \tkxorb %k7,%k6,%k5",},
193{{0xc4, 0xe1, 0xcd, 0x47, 0xef, }, 5, 0, "", "",
194"c4 e1 cd 47 ef \tkxord %k7,%k6,%k5",},
195{{0xc5, 0xcc, 0x4a, 0xef, }, 4, 0, "", "",
196"c5 cc 4a ef \tkaddw %k7,%k6,%k5",},
197{{0xc4, 0xe1, 0xcc, 0x4a, 0xef, }, 5, 0, "", "",
198"c4 e1 cc 4a ef \tkaddq %k7,%k6,%k5",},
199{{0xc5, 0xcd, 0x4a, 0xef, }, 4, 0, "", "",
200"c5 cd 4a ef \tkaddb %k7,%k6,%k5",},
201{{0xc4, 0xe1, 0xcd, 0x4a, 0xef, }, 5, 0, "", "",
202"c4 e1 cd 4a ef \tkaddd %k7,%k6,%k5",},
203{{0xc5, 0xcd, 0x4b, 0xef, }, 4, 0, "", "",
204"c5 cd 4b ef \tkunpckbw %k7,%k6,%k5",},
205{{0xc5, 0xcc, 0x4b, 0xef, }, 4, 0, "", "",
206"c5 cc 4b ef \tkunpckwd %k7,%k6,%k5",},
207{{0xc4, 0xe1, 0xcc, 0x4b, 0xef, }, 5, 0, "", "",
208"c4 e1 cc 4b ef \tkunpckdq %k7,%k6,%k5",},
209{{0xc5, 0xf8, 0x90, 0xee, }, 4, 0, "", "",
210"c5 f8 90 ee \tkmovw %k6,%k5",},
211{{0xc5, 0xf8, 0x90, 0x29, }, 4, 0, "", "",
212"c5 f8 90 29 \tkmovw (%ecx),%k5",},
213{{0xc5, 0xf8, 0x90, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 9, 0, "", "",
214"c5 f8 90 ac c8 23 01 00 00 \tkmovw 0x123(%eax,%ecx,8),%k5",},
215{{0xc5, 0xf8, 0x91, 0x29, }, 4, 0, "", "",
216"c5 f8 91 29 \tkmovw %k5,(%ecx)",},
217{{0xc5, 0xf8, 0x91, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 9, 0, "", "",
218"c5 f8 91 ac c8 23 01 00 00 \tkmovw %k5,0x123(%eax,%ecx,8)",},
219{{0xc5, 0xf8, 0x92, 0xe8, }, 4, 0, "", "",
220"c5 f8 92 e8 \tkmovw %eax,%k5",},
221{{0xc5, 0xf8, 0x92, 0xed, }, 4, 0, "", "",
222"c5 f8 92 ed \tkmovw %ebp,%k5",},
223{{0xc5, 0xf8, 0x93, 0xc5, }, 4, 0, "", "",
224"c5 f8 93 c5 \tkmovw %k5,%eax",},
225{{0xc5, 0xf8, 0x93, 0xed, }, 4, 0, "", "",
226"c5 f8 93 ed \tkmovw %k5,%ebp",},
227{{0xc4, 0xe1, 0xf8, 0x90, 0xee, }, 5, 0, "", "",
228"c4 e1 f8 90 ee \tkmovq %k6,%k5",},
229{{0xc4, 0xe1, 0xf8, 0x90, 0x29, }, 5, 0, "", "",
230"c4 e1 f8 90 29 \tkmovq (%ecx),%k5",},
231{{0xc4, 0xe1, 0xf8, 0x90, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
232"c4 e1 f8 90 ac c8 23 01 00 00 \tkmovq 0x123(%eax,%ecx,8),%k5",},
233{{0xc4, 0xe1, 0xf8, 0x91, 0x29, }, 5, 0, "", "",
234"c4 e1 f8 91 29 \tkmovq %k5,(%ecx)",},
235{{0xc4, 0xe1, 0xf8, 0x91, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
236"c4 e1 f8 91 ac c8 23 01 00 00 \tkmovq %k5,0x123(%eax,%ecx,8)",},
237{{0xc5, 0xf9, 0x90, 0xee, }, 4, 0, "", "",
238"c5 f9 90 ee \tkmovb %k6,%k5",},
239{{0xc5, 0xf9, 0x90, 0x29, }, 4, 0, "", "",
240"c5 f9 90 29 \tkmovb (%ecx),%k5",},
241{{0xc5, 0xf9, 0x90, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 9, 0, "", "",
242"c5 f9 90 ac c8 23 01 00 00 \tkmovb 0x123(%eax,%ecx,8),%k5",},
243{{0xc5, 0xf9, 0x91, 0x29, }, 4, 0, "", "",
244"c5 f9 91 29 \tkmovb %k5,(%ecx)",},
245{{0xc5, 0xf9, 0x91, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 9, 0, "", "",
246"c5 f9 91 ac c8 23 01 00 00 \tkmovb %k5,0x123(%eax,%ecx,8)",},
247{{0xc5, 0xf9, 0x92, 0xe8, }, 4, 0, "", "",
248"c5 f9 92 e8 \tkmovb %eax,%k5",},
249{{0xc5, 0xf9, 0x92, 0xed, }, 4, 0, "", "",
250"c5 f9 92 ed \tkmovb %ebp,%k5",},
251{{0xc5, 0xf9, 0x93, 0xc5, }, 4, 0, "", "",
252"c5 f9 93 c5 \tkmovb %k5,%eax",},
253{{0xc5, 0xf9, 0x93, 0xed, }, 4, 0, "", "",
254"c5 f9 93 ed \tkmovb %k5,%ebp",},
255{{0xc4, 0xe1, 0xf9, 0x90, 0xee, }, 5, 0, "", "",
256"c4 e1 f9 90 ee \tkmovd %k6,%k5",},
257{{0xc4, 0xe1, 0xf9, 0x90, 0x29, }, 5, 0, "", "",
258"c4 e1 f9 90 29 \tkmovd (%ecx),%k5",},
259{{0xc4, 0xe1, 0xf9, 0x90, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
260"c4 e1 f9 90 ac c8 23 01 00 00 \tkmovd 0x123(%eax,%ecx,8),%k5",},
261{{0xc4, 0xe1, 0xf9, 0x91, 0x29, }, 5, 0, "", "",
262"c4 e1 f9 91 29 \tkmovd %k5,(%ecx)",},
263{{0xc4, 0xe1, 0xf9, 0x91, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
264"c4 e1 f9 91 ac c8 23 01 00 00 \tkmovd %k5,0x123(%eax,%ecx,8)",},
265{{0xc5, 0xfb, 0x92, 0xe8, }, 4, 0, "", "",
266"c5 fb 92 e8 \tkmovd %eax,%k5",},
267{{0xc5, 0xfb, 0x92, 0xed, }, 4, 0, "", "",
268"c5 fb 92 ed \tkmovd %ebp,%k5",},
269{{0xc5, 0xfb, 0x93, 0xc5, }, 4, 0, "", "",
270"c5 fb 93 c5 \tkmovd %k5,%eax",},
271{{0xc5, 0xfb, 0x93, 0xed, }, 4, 0, "", "",
272"c5 fb 93 ed \tkmovd %k5,%ebp",},
273{{0xc5, 0xf8, 0x98, 0xee, }, 4, 0, "", "",
274"c5 f8 98 ee \tkortestw %k6,%k5",},
275{{0xc4, 0xe1, 0xf8, 0x98, 0xee, }, 5, 0, "", "",
276"c4 e1 f8 98 ee \tkortestq %k6,%k5",},
277{{0xc5, 0xf9, 0x98, 0xee, }, 4, 0, "", "",
278"c5 f9 98 ee \tkortestb %k6,%k5",},
279{{0xc4, 0xe1, 0xf9, 0x98, 0xee, }, 5, 0, "", "",
280"c4 e1 f9 98 ee \tkortestd %k6,%k5",},
281{{0xc5, 0xf8, 0x99, 0xee, }, 4, 0, "", "",
282"c5 f8 99 ee \tktestw %k6,%k5",},
283{{0xc4, 0xe1, 0xf8, 0x99, 0xee, }, 5, 0, "", "",
284"c4 e1 f8 99 ee \tktestq %k6,%k5",},
285{{0xc5, 0xf9, 0x99, 0xee, }, 4, 0, "", "",
286"c5 f9 99 ee \tktestb %k6,%k5",},
287{{0xc4, 0xe1, 0xf9, 0x99, 0xee, }, 5, 0, "", "",
288"c4 e1 f9 99 ee \tktestd %k6,%k5",},
289{{0xc4, 0xe3, 0xf9, 0x30, 0xee, 0x12, }, 6, 0, "", "",
290"c4 e3 f9 30 ee 12 \tkshiftrw $0x12,%k6,%k5",},
291{{0xc4, 0xe3, 0xf9, 0x31, 0xee, 0x5b, }, 6, 0, "", "",
292"c4 e3 f9 31 ee 5b \tkshiftrq $0x5b,%k6,%k5",},
293{{0xc4, 0xe3, 0xf9, 0x32, 0xee, 0x12, }, 6, 0, "", "",
294"c4 e3 f9 32 ee 12 \tkshiftlw $0x12,%k6,%k5",},
295{{0xc4, 0xe3, 0xf9, 0x33, 0xee, 0x5b, }, 6, 0, "", "",
296"c4 e3 f9 33 ee 5b \tkshiftlq $0x5b,%k6,%k5",},
297{{0xc5, 0xf8, 0x5b, 0xf5, }, 4, 0, "", "",
298"c5 f8 5b f5 \tvcvtdq2ps %xmm5,%xmm6",},
299{{0x62, 0xf1, 0xfc, 0x4f, 0x5b, 0xf5, }, 6, 0, "", "",
300"62 f1 fc 4f 5b f5 \tvcvtqq2ps %zmm5,%ymm6{%k7}",},
301{{0xc5, 0xf9, 0x5b, 0xf5, }, 4, 0, "", "",
302"c5 f9 5b f5 \tvcvtps2dq %xmm5,%xmm6",},
303{{0xc5, 0xfa, 0x5b, 0xf5, }, 4, 0, "", "",
304"c5 fa 5b f5 \tvcvttps2dq %xmm5,%xmm6",},
305{{0x0f, 0x6f, 0xe0, }, 3, 0, "", "",
306"0f 6f e0 \tmovq %mm0,%mm4",},
307{{0xc5, 0xfd, 0x6f, 0xf4, }, 4, 0, "", "",
308"c5 fd 6f f4 \tvmovdqa %ymm4,%ymm6",},
309{{0x62, 0xf1, 0x7d, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
310"62 f1 7d 48 6f f5 \tvmovdqa32 %zmm5,%zmm6",},
311{{0x62, 0xf1, 0xfd, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
312"62 f1 fd 48 6f f5 \tvmovdqa64 %zmm5,%zmm6",},
313{{0xc5, 0xfe, 0x6f, 0xf4, }, 4, 0, "", "",
314"c5 fe 6f f4 \tvmovdqu %ymm4,%ymm6",},
315{{0x62, 0xf1, 0x7e, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
316"62 f1 7e 48 6f f5 \tvmovdqu32 %zmm5,%zmm6",},
317{{0x62, 0xf1, 0xfe, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
318"62 f1 fe 48 6f f5 \tvmovdqu64 %zmm5,%zmm6",},
319{{0x62, 0xf1, 0x7f, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
320"62 f1 7f 48 6f f5 \tvmovdqu8 %zmm5,%zmm6",},
321{{0x62, 0xf1, 0xff, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
322"62 f1 ff 48 6f f5 \tvmovdqu16 %zmm5,%zmm6",},
323{{0x0f, 0x78, 0xc3, }, 3, 0, "", "",
324"0f 78 c3 \tvmread %eax,%ebx",},
325{{0x62, 0xf1, 0x7c, 0x48, 0x78, 0xf5, }, 6, 0, "", "",
326"62 f1 7c 48 78 f5 \tvcvttps2udq %zmm5,%zmm6",},
327{{0x62, 0xf1, 0xfc, 0x4f, 0x78, 0xf5, }, 6, 0, "", "",
328"62 f1 fc 4f 78 f5 \tvcvttpd2udq %zmm5,%ymm6{%k7}",},
329{{0x62, 0xf1, 0x7f, 0x08, 0x78, 0xc6, }, 6, 0, "", "",
330"62 f1 7f 08 78 c6 \tvcvttsd2usi %xmm6,%eax",},
331{{0x62, 0xf1, 0x7e, 0x08, 0x78, 0xc6, }, 6, 0, "", "",
332"62 f1 7e 08 78 c6 \tvcvttss2usi %xmm6,%eax",},
333{{0x62, 0xf1, 0x7d, 0x4f, 0x78, 0xf5, }, 6, 0, "", "",
334"62 f1 7d 4f 78 f5 \tvcvttps2uqq %ymm5,%zmm6{%k7}",},
335{{0x62, 0xf1, 0xfd, 0x48, 0x78, 0xf5, }, 6, 0, "", "",
336"62 f1 fd 48 78 f5 \tvcvttpd2uqq %zmm5,%zmm6",},
337{{0x0f, 0x79, 0xd8, }, 3, 0, "", "",
338"0f 79 d8 \tvmwrite %eax,%ebx",},
339{{0x62, 0xf1, 0x7c, 0x48, 0x79, 0xf5, }, 6, 0, "", "",
340"62 f1 7c 48 79 f5 \tvcvtps2udq %zmm5,%zmm6",},
341{{0x62, 0xf1, 0xfc, 0x4f, 0x79, 0xf5, }, 6, 0, "", "",
342"62 f1 fc 4f 79 f5 \tvcvtpd2udq %zmm5,%ymm6{%k7}",},
343{{0x62, 0xf1, 0x7f, 0x08, 0x79, 0xc6, }, 6, 0, "", "",
344"62 f1 7f 08 79 c6 \tvcvtsd2usi %xmm6,%eax",},
345{{0x62, 0xf1, 0x7e, 0x08, 0x79, 0xc6, }, 6, 0, "", "",
346"62 f1 7e 08 79 c6 \tvcvtss2usi %xmm6,%eax",},
347{{0x62, 0xf1, 0x7d, 0x4f, 0x79, 0xf5, }, 6, 0, "", "",
348"62 f1 7d 4f 79 f5 \tvcvtps2uqq %ymm5,%zmm6{%k7}",},
349{{0x62, 0xf1, 0xfd, 0x48, 0x79, 0xf5, }, 6, 0, "", "",
350"62 f1 fd 48 79 f5 \tvcvtpd2uqq %zmm5,%zmm6",},
351{{0x62, 0xf1, 0x7e, 0x4f, 0x7a, 0xf5, }, 6, 0, "", "",
352"62 f1 7e 4f 7a f5 \tvcvtudq2pd %ymm5,%zmm6{%k7}",},
353{{0x62, 0xf1, 0xfe, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
354"62 f1 fe 48 7a f5 \tvcvtuqq2pd %zmm5,%zmm6",},
355{{0x62, 0xf1, 0x7f, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
356"62 f1 7f 48 7a f5 \tvcvtudq2ps %zmm5,%zmm6",},
357{{0x62, 0xf1, 0xff, 0x4f, 0x7a, 0xf5, }, 6, 0, "", "",
358"62 f1 ff 4f 7a f5 \tvcvtuqq2ps %zmm5,%ymm6{%k7}",},
359{{0x62, 0xf1, 0x7d, 0x4f, 0x7a, 0xf5, }, 6, 0, "", "",
360"62 f1 7d 4f 7a f5 \tvcvttps2qq %ymm5,%zmm6{%k7}",},
361{{0x62, 0xf1, 0xfd, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
362"62 f1 fd 48 7a f5 \tvcvttpd2qq %zmm5,%zmm6",},
363{{0x62, 0xf1, 0x57, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
364"62 f1 57 08 7b f0 \tvcvtusi2sd %eax,%xmm5,%xmm6",},
365{{0x62, 0xf1, 0x56, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
366"62 f1 56 08 7b f0 \tvcvtusi2ss %eax,%xmm5,%xmm6",},
367{{0x62, 0xf1, 0x7d, 0x4f, 0x7b, 0xf5, }, 6, 0, "", "",
368"62 f1 7d 4f 7b f5 \tvcvtps2qq %ymm5,%zmm6{%k7}",},
369{{0x62, 0xf1, 0xfd, 0x48, 0x7b, 0xf5, }, 6, 0, "", "",
370"62 f1 fd 48 7b f5 \tvcvtpd2qq %zmm5,%zmm6",},
371{{0x0f, 0x7f, 0xc4, }, 3, 0, "", "",
372"0f 7f c4 \tmovq %mm0,%mm4",},
373{{0xc5, 0xfd, 0x7f, 0xee, }, 4, 0, "", "",
374"c5 fd 7f ee \tvmovdqa %ymm5,%ymm6",},
375{{0x62, 0xf1, 0x7d, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
376"62 f1 7d 48 7f ee \tvmovdqa32 %zmm5,%zmm6",},
377{{0x62, 0xf1, 0xfd, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
378"62 f1 fd 48 7f ee \tvmovdqa64 %zmm5,%zmm6",},
379{{0xc5, 0xfe, 0x7f, 0xee, }, 4, 0, "", "",
380"c5 fe 7f ee \tvmovdqu %ymm5,%ymm6",},
381{{0x62, 0xf1, 0x7e, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
382"62 f1 7e 48 7f ee \tvmovdqu32 %zmm5,%zmm6",},
383{{0x62, 0xf1, 0xfe, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
384"62 f1 fe 48 7f ee \tvmovdqu64 %zmm5,%zmm6",},
385{{0x62, 0xf1, 0x7f, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
386"62 f1 7f 48 7f ee \tvmovdqu8 %zmm5,%zmm6",},
387{{0x62, 0xf1, 0xff, 0x48, 0x7f, 0xee, }, 6, 0, "", "",
388"62 f1 ff 48 7f ee \tvmovdqu16 %zmm5,%zmm6",},
389{{0x0f, 0xdb, 0xd1, }, 3, 0, "", "",
390"0f db d1 \tpand %mm1,%mm2",},
391{{0x66, 0x0f, 0xdb, 0xd1, }, 4, 0, "", "",
392"66 0f db d1 \tpand %xmm1,%xmm2",},
393{{0xc5, 0xcd, 0xdb, 0xd4, }, 4, 0, "", "",
394"c5 cd db d4 \tvpand %ymm4,%ymm6,%ymm2",},
395{{0x62, 0xf1, 0x55, 0x48, 0xdb, 0xf4, }, 6, 0, "", "",
396"62 f1 55 48 db f4 \tvpandd %zmm4,%zmm5,%zmm6",},
397{{0x62, 0xf1, 0xd5, 0x48, 0xdb, 0xf4, }, 6, 0, "", "",
398"62 f1 d5 48 db f4 \tvpandq %zmm4,%zmm5,%zmm6",},
399{{0x0f, 0xdf, 0xd1, }, 3, 0, "", "",
400"0f df d1 \tpandn %mm1,%mm2",},
401{{0x66, 0x0f, 0xdf, 0xd1, }, 4, 0, "", "",
402"66 0f df d1 \tpandn %xmm1,%xmm2",},
403{{0xc5, 0xcd, 0xdf, 0xd4, }, 4, 0, "", "",
404"c5 cd df d4 \tvpandn %ymm4,%ymm6,%ymm2",},
405{{0x62, 0xf1, 0x55, 0x48, 0xdf, 0xf4, }, 6, 0, "", "",
406"62 f1 55 48 df f4 \tvpandnd %zmm4,%zmm5,%zmm6",},
407{{0x62, 0xf1, 0xd5, 0x48, 0xdf, 0xf4, }, 6, 0, "", "",
408"62 f1 d5 48 df f4 \tvpandnq %zmm4,%zmm5,%zmm6",},
409{{0xc5, 0xf9, 0xe6, 0xd1, }, 4, 0, "", "",
410"c5 f9 e6 d1 \tvcvttpd2dq %xmm1,%xmm2",},
411{{0xc5, 0xfa, 0xe6, 0xf5, }, 4, 0, "", "",
412"c5 fa e6 f5 \tvcvtdq2pd %xmm5,%xmm6",},
413{{0x62, 0xf1, 0x7e, 0x4f, 0xe6, 0xf5, }, 6, 0, "", "",
414"62 f1 7e 4f e6 f5 \tvcvtdq2pd %ymm5,%zmm6{%k7}",},
415{{0x62, 0xf1, 0xfe, 0x48, 0xe6, 0xf5, }, 6, 0, "", "",
416"62 f1 fe 48 e6 f5 \tvcvtqq2pd %zmm5,%zmm6",},
417{{0xc5, 0xfb, 0xe6, 0xd1, }, 4, 0, "", "",
418"c5 fb e6 d1 \tvcvtpd2dq %xmm1,%xmm2",},
419{{0x0f, 0xeb, 0xf4, }, 3, 0, "", "",
420"0f eb f4 \tpor %mm4,%mm6",},
421{{0xc5, 0xcd, 0xeb, 0xd4, }, 4, 0, "", "",
422"c5 cd eb d4 \tvpor %ymm4,%ymm6,%ymm2",},
423{{0x62, 0xf1, 0x55, 0x48, 0xeb, 0xf4, }, 6, 0, "", "",
424"62 f1 55 48 eb f4 \tvpord %zmm4,%zmm5,%zmm6",},
425{{0x62, 0xf1, 0xd5, 0x48, 0xeb, 0xf4, }, 6, 0, "", "",
426"62 f1 d5 48 eb f4 \tvporq %zmm4,%zmm5,%zmm6",},
427{{0x0f, 0xef, 0xf4, }, 3, 0, "", "",
428"0f ef f4 \tpxor %mm4,%mm6",},
429{{0xc5, 0xcd, 0xef, 0xd4, }, 4, 0, "", "",
430"c5 cd ef d4 \tvpxor %ymm4,%ymm6,%ymm2",},
431{{0x62, 0xf1, 0x55, 0x48, 0xef, 0xf4, }, 6, 0, "", "",
432"62 f1 55 48 ef f4 \tvpxord %zmm4,%zmm5,%zmm6",},
433{{0x62, 0xf1, 0xd5, 0x48, 0xef, 0xf4, }, 6, 0, "", "",
434"62 f1 d5 48 ef f4 \tvpxorq %zmm4,%zmm5,%zmm6",},
435{{0x66, 0x0f, 0x38, 0x10, 0xc1, }, 5, 0, "", "",
436"66 0f 38 10 c1 \tpblendvb %xmm0,%xmm1,%xmm0",},
437{{0x62, 0xf2, 0xd5, 0x48, 0x10, 0xf4, }, 6, 0, "", "",
438"62 f2 d5 48 10 f4 \tvpsrlvw %zmm4,%zmm5,%zmm6",},
439{{0x62, 0xf2, 0x7e, 0x4f, 0x10, 0xee, }, 6, 0, "", "",
440"62 f2 7e 4f 10 ee \tvpmovuswb %zmm5,%ymm6{%k7}",},
441{{0x62, 0xf2, 0x7e, 0x4f, 0x11, 0xee, }, 6, 0, "", "",
442"62 f2 7e 4f 11 ee \tvpmovusdb %zmm5,%xmm6{%k7}",},
443{{0x62, 0xf2, 0xd5, 0x48, 0x11, 0xf4, }, 6, 0, "", "",
444"62 f2 d5 48 11 f4 \tvpsravw %zmm4,%zmm5,%zmm6",},
445{{0x62, 0xf2, 0x7e, 0x4f, 0x12, 0xee, }, 6, 0, "", "",
446"62 f2 7e 4f 12 ee \tvpmovusqb %zmm5,%xmm6{%k7}",},
447{{0x62, 0xf2, 0xd5, 0x48, 0x12, 0xf4, }, 6, 0, "", "",
448"62 f2 d5 48 12 f4 \tvpsllvw %zmm4,%zmm5,%zmm6",},
449{{0xc4, 0xe2, 0x7d, 0x13, 0xeb, }, 5, 0, "", "",
450"c4 e2 7d 13 eb \tvcvtph2ps %xmm3,%ymm5",},
451{{0x62, 0xf2, 0x7d, 0x4f, 0x13, 0xf5, }, 6, 0, "", "",
452"62 f2 7d 4f 13 f5 \tvcvtph2ps %ymm5,%zmm6{%k7}",},
453{{0x62, 0xf2, 0x7e, 0x4f, 0x13, 0xee, }, 6, 0, "", "",
454"62 f2 7e 4f 13 ee \tvpmovusdw %zmm5,%ymm6{%k7}",},
455{{0x66, 0x0f, 0x38, 0x14, 0xc1, }, 5, 0, "", "",
456"66 0f 38 14 c1 \tblendvps %xmm0,%xmm1,%xmm0",},
457{{0x62, 0xf2, 0x7e, 0x4f, 0x14, 0xee, }, 6, 0, "", "",
458"62 f2 7e 4f 14 ee \tvpmovusqw %zmm5,%xmm6{%k7}",},
459{{0x62, 0xf2, 0x55, 0x48, 0x14, 0xf4, }, 6, 0, "", "",
460"62 f2 55 48 14 f4 \tvprorvd %zmm4,%zmm5,%zmm6",},
461{{0x62, 0xf2, 0xd5, 0x48, 0x14, 0xf4, }, 6, 0, "", "",
462"62 f2 d5 48 14 f4 \tvprorvq %zmm4,%zmm5,%zmm6",},
463{{0x66, 0x0f, 0x38, 0x15, 0xc1, }, 5, 0, "", "",
464"66 0f 38 15 c1 \tblendvpd %xmm0,%xmm1,%xmm0",},
465{{0x62, 0xf2, 0x7e, 0x4f, 0x15, 0xee, }, 6, 0, "", "",
466"62 f2 7e 4f 15 ee \tvpmovusqd %zmm5,%ymm6{%k7}",},
467{{0x62, 0xf2, 0x55, 0x48, 0x15, 0xf4, }, 6, 0, "", "",
468"62 f2 55 48 15 f4 \tvprolvd %zmm4,%zmm5,%zmm6",},
469{{0x62, 0xf2, 0xd5, 0x48, 0x15, 0xf4, }, 6, 0, "", "",
470"62 f2 d5 48 15 f4 \tvprolvq %zmm4,%zmm5,%zmm6",},
471{{0xc4, 0xe2, 0x4d, 0x16, 0xd4, }, 5, 0, "", "",
472"c4 e2 4d 16 d4 \tvpermps %ymm4,%ymm6,%ymm2",},
473{{0x62, 0xf2, 0x4d, 0x2f, 0x16, 0xd4, }, 6, 0, "", "",
474"62 f2 4d 2f 16 d4 \tvpermps %ymm4,%ymm6,%ymm2{%k7}",},
475{{0x62, 0xf2, 0xcd, 0x2f, 0x16, 0xd4, }, 6, 0, "", "",
476"62 f2 cd 2f 16 d4 \tvpermpd %ymm4,%ymm6,%ymm2{%k7}",},
477{{0xc4, 0xe2, 0x7d, 0x19, 0xf4, }, 5, 0, "", "",
478"c4 e2 7d 19 f4 \tvbroadcastsd %xmm4,%ymm6",},
479{{0x62, 0xf2, 0x7d, 0x48, 0x19, 0xf7, }, 6, 0, "", "",
480"62 f2 7d 48 19 f7 \tvbroadcastf32x2 %xmm7,%zmm6",},
481{{0xc4, 0xe2, 0x7d, 0x1a, 0x21, }, 5, 0, "", "",
482"c4 e2 7d 1a 21 \tvbroadcastf128 (%ecx),%ymm4",},
483{{0x62, 0xf2, 0x7d, 0x48, 0x1a, 0x31, }, 6, 0, "", "",
484"62 f2 7d 48 1a 31 \tvbroadcastf32x4 (%ecx),%zmm6",},
485{{0x62, 0xf2, 0xfd, 0x48, 0x1a, 0x31, }, 6, 0, "", "",
486"62 f2 fd 48 1a 31 \tvbroadcastf64x2 (%ecx),%zmm6",},
487{{0x62, 0xf2, 0x7d, 0x48, 0x1b, 0x31, }, 6, 0, "", "",
488"62 f2 7d 48 1b 31 \tvbroadcastf32x8 (%ecx),%zmm6",},
489{{0x62, 0xf2, 0xfd, 0x48, 0x1b, 0x31, }, 6, 0, "", "",
490"62 f2 fd 48 1b 31 \tvbroadcastf64x4 (%ecx),%zmm6",},
491{{0x62, 0xf2, 0xfd, 0x48, 0x1f, 0xf4, }, 6, 0, "", "",
492"62 f2 fd 48 1f f4 \tvpabsq %zmm4,%zmm6",},
493{{0xc4, 0xe2, 0x79, 0x20, 0xec, }, 5, 0, "", "",
494"c4 e2 79 20 ec \tvpmovsxbw %xmm4,%xmm5",},
495{{0x62, 0xf2, 0x7e, 0x4f, 0x20, 0xee, }, 6, 0, "", "",
496"62 f2 7e 4f 20 ee \tvpmovswb %zmm5,%ymm6{%k7}",},
497{{0xc4, 0xe2, 0x7d, 0x21, 0xf4, }, 5, 0, "", "",
498"c4 e2 7d 21 f4 \tvpmovsxbd %xmm4,%ymm6",},
499{{0x62, 0xf2, 0x7e, 0x4f, 0x21, 0xee, }, 6, 0, "", "",
500"62 f2 7e 4f 21 ee \tvpmovsdb %zmm5,%xmm6{%k7}",},
501{{0xc4, 0xe2, 0x7d, 0x22, 0xe4, }, 5, 0, "", "",
502"c4 e2 7d 22 e4 \tvpmovsxbq %xmm4,%ymm4",},
503{{0x62, 0xf2, 0x7e, 0x4f, 0x22, 0xee, }, 6, 0, "", "",
504"62 f2 7e 4f 22 ee \tvpmovsqb %zmm5,%xmm6{%k7}",},
505{{0xc4, 0xe2, 0x7d, 0x23, 0xe4, }, 5, 0, "", "",
506"c4 e2 7d 23 e4 \tvpmovsxwd %xmm4,%ymm4",},
507{{0x62, 0xf2, 0x7e, 0x4f, 0x23, 0xee, }, 6, 0, "", "",
508"62 f2 7e 4f 23 ee \tvpmovsdw %zmm5,%ymm6{%k7}",},
509{{0xc4, 0xe2, 0x7d, 0x24, 0xf4, }, 5, 0, "", "",
510"c4 e2 7d 24 f4 \tvpmovsxwq %xmm4,%ymm6",},
511{{0x62, 0xf2, 0x7e, 0x4f, 0x24, 0xee, }, 6, 0, "", "",
512"62 f2 7e 4f 24 ee \tvpmovsqw %zmm5,%xmm6{%k7}",},
513{{0xc4, 0xe2, 0x7d, 0x25, 0xe4, }, 5, 0, "", "",
514"c4 e2 7d 25 e4 \tvpmovsxdq %xmm4,%ymm4",},
515{{0x62, 0xf2, 0x7e, 0x4f, 0x25, 0xee, }, 6, 0, "", "",
516"62 f2 7e 4f 25 ee \tvpmovsqd %zmm5,%ymm6{%k7}",},
517{{0x62, 0xf2, 0x4d, 0x48, 0x26, 0xed, }, 6, 0, "", "",
518"62 f2 4d 48 26 ed \tvptestmb %zmm5,%zmm6,%k5",},
519{{0x62, 0xf2, 0xcd, 0x48, 0x26, 0xed, }, 6, 0, "", "",
520"62 f2 cd 48 26 ed \tvptestmw %zmm5,%zmm6,%k5",},
521{{0x62, 0xf2, 0x56, 0x48, 0x26, 0xec, }, 6, 0, "", "",
522"62 f2 56 48 26 ec \tvptestnmb %zmm4,%zmm5,%k5",},
523{{0x62, 0xf2, 0xd6, 0x48, 0x26, 0xec, }, 6, 0, "", "",
524"62 f2 d6 48 26 ec \tvptestnmw %zmm4,%zmm5,%k5",},
525{{0x62, 0xf2, 0x4d, 0x48, 0x27, 0xed, }, 6, 0, "", "",
526"62 f2 4d 48 27 ed \tvptestmd %zmm5,%zmm6,%k5",},
527{{0x62, 0xf2, 0xcd, 0x48, 0x27, 0xed, }, 6, 0, "", "",
528"62 f2 cd 48 27 ed \tvptestmq %zmm5,%zmm6,%k5",},
529{{0x62, 0xf2, 0x56, 0x48, 0x27, 0xec, }, 6, 0, "", "",
530"62 f2 56 48 27 ec \tvptestnmd %zmm4,%zmm5,%k5",},
531{{0x62, 0xf2, 0xd6, 0x48, 0x27, 0xec, }, 6, 0, "", "",
532"62 f2 d6 48 27 ec \tvptestnmq %zmm4,%zmm5,%k5",},
533{{0xc4, 0xe2, 0x4d, 0x28, 0xd4, }, 5, 0, "", "",
534"c4 e2 4d 28 d4 \tvpmuldq %ymm4,%ymm6,%ymm2",},
535{{0x62, 0xf2, 0x7e, 0x48, 0x28, 0xf5, }, 6, 0, "", "",
536"62 f2 7e 48 28 f5 \tvpmovm2b %k5,%zmm6",},
537{{0x62, 0xf2, 0xfe, 0x48, 0x28, 0xf5, }, 6, 0, "", "",
538"62 f2 fe 48 28 f5 \tvpmovm2w %k5,%zmm6",},
539{{0xc4, 0xe2, 0x4d, 0x29, 0xd4, }, 5, 0, "", "",
540"c4 e2 4d 29 d4 \tvpcmpeqq %ymm4,%ymm6,%ymm2",},
541{{0x62, 0xf2, 0x7e, 0x48, 0x29, 0xee, }, 6, 0, "", "",
542"62 f2 7e 48 29 ee \tvpmovb2m %zmm6,%k5",},
543{{0x62, 0xf2, 0xfe, 0x48, 0x29, 0xee, }, 6, 0, "", "",
544"62 f2 fe 48 29 ee \tvpmovw2m %zmm6,%k5",},
545{{0xc4, 0xe2, 0x7d, 0x2a, 0x21, }, 5, 0, "", "",
546"c4 e2 7d 2a 21 \tvmovntdqa (%ecx),%ymm4",},
547{{0x62, 0xf2, 0xfe, 0x48, 0x2a, 0xce, }, 6, 0, "", "",
548"62 f2 fe 48 2a ce \tvpbroadcastmb2q %k6,%zmm1",},
549{{0xc4, 0xe2, 0x5d, 0x2c, 0x31, }, 5, 0, "", "",
550"c4 e2 5d 2c 31 \tvmaskmovps (%ecx),%ymm4,%ymm6",},
551{{0x62, 0xf2, 0x55, 0x48, 0x2c, 0xf4, }, 6, 0, "", "",
552"62 f2 55 48 2c f4 \tvscalefps %zmm4,%zmm5,%zmm6",},
553{{0x62, 0xf2, 0xd5, 0x48, 0x2c, 0xf4, }, 6, 0, "", "",
554"62 f2 d5 48 2c f4 \tvscalefpd %zmm4,%zmm5,%zmm6",},
555{{0xc4, 0xe2, 0x5d, 0x2d, 0x31, }, 5, 0, "", "",
556"c4 e2 5d 2d 31 \tvmaskmovpd (%ecx),%ymm4,%ymm6",},
557{{0x62, 0xf2, 0x55, 0x0f, 0x2d, 0xf4, }, 6, 0, "", "",
558"62 f2 55 0f 2d f4 \tvscalefss %xmm4,%xmm5,%xmm6{%k7}",},
559{{0x62, 0xf2, 0xd5, 0x0f, 0x2d, 0xf4, }, 6, 0, "", "",
560"62 f2 d5 0f 2d f4 \tvscalefsd %xmm4,%xmm5,%xmm6{%k7}",},
561{{0xc4, 0xe2, 0x7d, 0x30, 0xe4, }, 5, 0, "", "",
562"c4 e2 7d 30 e4 \tvpmovzxbw %xmm4,%ymm4",},
563{{0x62, 0xf2, 0x7e, 0x4f, 0x30, 0xee, }, 6, 0, "", "",
564"62 f2 7e 4f 30 ee \tvpmovwb %zmm5,%ymm6{%k7}",},
565{{0xc4, 0xe2, 0x7d, 0x31, 0xf4, }, 5, 0, "", "",
566"c4 e2 7d 31 f4 \tvpmovzxbd %xmm4,%ymm6",},
567{{0x62, 0xf2, 0x7e, 0x4f, 0x31, 0xee, }, 6, 0, "", "",
568"62 f2 7e 4f 31 ee \tvpmovdb %zmm5,%xmm6{%k7}",},
569{{0xc4, 0xe2, 0x7d, 0x32, 0xe4, }, 5, 0, "", "",
570"c4 e2 7d 32 e4 \tvpmovzxbq %xmm4,%ymm4",},
571{{0x62, 0xf2, 0x7e, 0x4f, 0x32, 0xee, }, 6, 0, "", "",
572"62 f2 7e 4f 32 ee \tvpmovqb %zmm5,%xmm6{%k7}",},
573{{0xc4, 0xe2, 0x7d, 0x33, 0xe4, }, 5, 0, "", "",
574"c4 e2 7d 33 e4 \tvpmovzxwd %xmm4,%ymm4",},
575{{0x62, 0xf2, 0x7e, 0x4f, 0x33, 0xee, }, 6, 0, "", "",
576"62 f2 7e 4f 33 ee \tvpmovdw %zmm5,%ymm6{%k7}",},
577{{0xc4, 0xe2, 0x7d, 0x34, 0xf4, }, 5, 0, "", "",
578"c4 e2 7d 34 f4 \tvpmovzxwq %xmm4,%ymm6",},
579{{0x62, 0xf2, 0x7e, 0x4f, 0x34, 0xee, }, 6, 0, "", "",
580"62 f2 7e 4f 34 ee \tvpmovqw %zmm5,%xmm6{%k7}",},
581{{0xc4, 0xe2, 0x7d, 0x35, 0xe4, }, 5, 0, "", "",
582"c4 e2 7d 35 e4 \tvpmovzxdq %xmm4,%ymm4",},
583{{0x62, 0xf2, 0x7e, 0x4f, 0x35, 0xee, }, 6, 0, "", "",
584"62 f2 7e 4f 35 ee \tvpmovqd %zmm5,%ymm6{%k7}",},
585{{0xc4, 0xe2, 0x4d, 0x36, 0xd4, }, 5, 0, "", "",
586"c4 e2 4d 36 d4 \tvpermd %ymm4,%ymm6,%ymm2",},
587{{0x62, 0xf2, 0x4d, 0x2f, 0x36, 0xd4, }, 6, 0, "", "",
588"62 f2 4d 2f 36 d4 \tvpermd %ymm4,%ymm6,%ymm2{%k7}",},
589{{0x62, 0xf2, 0xcd, 0x2f, 0x36, 0xd4, }, 6, 0, "", "",
590"62 f2 cd 2f 36 d4 \tvpermq %ymm4,%ymm6,%ymm2{%k7}",},
591{{0xc4, 0xe2, 0x4d, 0x38, 0xd4, }, 5, 0, "", "",
592"c4 e2 4d 38 d4 \tvpminsb %ymm4,%ymm6,%ymm2",},
593{{0x62, 0xf2, 0x7e, 0x48, 0x38, 0xf5, }, 6, 0, "", "",
594"62 f2 7e 48 38 f5 \tvpmovm2d %k5,%zmm6",},
595{{0x62, 0xf2, 0xfe, 0x48, 0x38, 0xf5, }, 6, 0, "", "",
596"62 f2 fe 48 38 f5 \tvpmovm2q %k5,%zmm6",},
597{{0xc4, 0xe2, 0x69, 0x39, 0xd9, }, 5, 0, "", "",
598"c4 e2 69 39 d9 \tvpminsd %xmm1,%xmm2,%xmm3",},
599{{0x62, 0xf2, 0x55, 0x48, 0x39, 0xf4, }, 6, 0, "", "",
600"62 f2 55 48 39 f4 \tvpminsd %zmm4,%zmm5,%zmm6",},
601{{0x62, 0xf2, 0xd5, 0x48, 0x39, 0xf4, }, 6, 0, "", "",
602"62 f2 d5 48 39 f4 \tvpminsq %zmm4,%zmm5,%zmm6",},
603{{0x62, 0xf2, 0x7e, 0x48, 0x39, 0xee, }, 6, 0, "", "",
604"62 f2 7e 48 39 ee \tvpmovd2m %zmm6,%k5",},
605{{0x62, 0xf2, 0xfe, 0x48, 0x39, 0xee, }, 6, 0, "", "",
606"62 f2 fe 48 39 ee \tvpmovq2m %zmm6,%k5",},
607{{0xc4, 0xe2, 0x4d, 0x3a, 0xd4, }, 5, 0, "", "",
608"c4 e2 4d 3a d4 \tvpminuw %ymm4,%ymm6,%ymm2",},
609{{0x62, 0xf2, 0x7e, 0x48, 0x3a, 0xf6, }, 6, 0, "", "",
610"62 f2 7e 48 3a f6 \tvpbroadcastmw2d %k6,%zmm6",},
611{{0xc4, 0xe2, 0x4d, 0x3b, 0xd4, }, 5, 0, "", "",
612"c4 e2 4d 3b d4 \tvpminud %ymm4,%ymm6,%ymm2",},
613{{0x62, 0xf2, 0x55, 0x48, 0x3b, 0xf4, }, 6, 0, "", "",
614"62 f2 55 48 3b f4 \tvpminud %zmm4,%zmm5,%zmm6",},
615{{0x62, 0xf2, 0xd5, 0x48, 0x3b, 0xf4, }, 6, 0, "", "",
616"62 f2 d5 48 3b f4 \tvpminuq %zmm4,%zmm5,%zmm6",},
617{{0xc4, 0xe2, 0x4d, 0x3d, 0xd4, }, 5, 0, "", "",
618"c4 e2 4d 3d d4 \tvpmaxsd %ymm4,%ymm6,%ymm2",},
619{{0x62, 0xf2, 0x55, 0x48, 0x3d, 0xf4, }, 6, 0, "", "",
620"62 f2 55 48 3d f4 \tvpmaxsd %zmm4,%zmm5,%zmm6",},
621{{0x62, 0xf2, 0xd5, 0x48, 0x3d, 0xf4, }, 6, 0, "", "",
622"62 f2 d5 48 3d f4 \tvpmaxsq %zmm4,%zmm5,%zmm6",},
623{{0xc4, 0xe2, 0x4d, 0x3f, 0xd4, }, 5, 0, "", "",
624"c4 e2 4d 3f d4 \tvpmaxud %ymm4,%ymm6,%ymm2",},
625{{0x62, 0xf2, 0x55, 0x48, 0x3f, 0xf4, }, 6, 0, "", "",
626"62 f2 55 48 3f f4 \tvpmaxud %zmm4,%zmm5,%zmm6",},
627{{0x62, 0xf2, 0xd5, 0x48, 0x3f, 0xf4, }, 6, 0, "", "",
628"62 f2 d5 48 3f f4 \tvpmaxuq %zmm4,%zmm5,%zmm6",},
629{{0xc4, 0xe2, 0x4d, 0x40, 0xd4, }, 5, 0, "", "",
630"c4 e2 4d 40 d4 \tvpmulld %ymm4,%ymm6,%ymm2",},
631{{0x62, 0xf2, 0x55, 0x48, 0x40, 0xf4, }, 6, 0, "", "",
632"62 f2 55 48 40 f4 \tvpmulld %zmm4,%zmm5,%zmm6",},
633{{0x62, 0xf2, 0xd5, 0x48, 0x40, 0xf4, }, 6, 0, "", "",
634"62 f2 d5 48 40 f4 \tvpmullq %zmm4,%zmm5,%zmm6",},
635{{0x62, 0xf2, 0x7d, 0x48, 0x42, 0xf5, }, 6, 0, "", "",
636"62 f2 7d 48 42 f5 \tvgetexpps %zmm5,%zmm6",},
637{{0x62, 0xf2, 0xfd, 0x48, 0x42, 0xf5, }, 6, 0, "", "",
638"62 f2 fd 48 42 f5 \tvgetexppd %zmm5,%zmm6",},
639{{0x62, 0xf2, 0x55, 0x0f, 0x43, 0xf4, }, 6, 0, "", "",
640"62 f2 55 0f 43 f4 \tvgetexpss %xmm4,%xmm5,%xmm6{%k7}",},
641{{0x62, 0xf2, 0xe5, 0x0f, 0x43, 0xe2, }, 6, 0, "", "",
642"62 f2 e5 0f 43 e2 \tvgetexpsd %xmm2,%xmm3,%xmm4{%k7}",},
643{{0x62, 0xf2, 0x7d, 0x48, 0x44, 0xf5, }, 6, 0, "", "",
644"62 f2 7d 48 44 f5 \tvplzcntd %zmm5,%zmm6",},
645{{0x62, 0xf2, 0xfd, 0x48, 0x44, 0xf5, }, 6, 0, "", "",
646"62 f2 fd 48 44 f5 \tvplzcntq %zmm5,%zmm6",},
647{{0xc4, 0xe2, 0x4d, 0x46, 0xd4, }, 5, 0, "", "",
648"c4 e2 4d 46 d4 \tvpsravd %ymm4,%ymm6,%ymm2",},
649{{0x62, 0xf2, 0x55, 0x48, 0x46, 0xf4, }, 6, 0, "", "",
650"62 f2 55 48 46 f4 \tvpsravd %zmm4,%zmm5,%zmm6",},
651{{0x62, 0xf2, 0xd5, 0x48, 0x46, 0xf4, }, 6, 0, "", "",
652"62 f2 d5 48 46 f4 \tvpsravq %zmm4,%zmm5,%zmm6",},
653{{0x62, 0xf2, 0x7d, 0x48, 0x4c, 0xf5, }, 6, 0, "", "",
654"62 f2 7d 48 4c f5 \tvrcp14ps %zmm5,%zmm6",},
655{{0x62, 0xf2, 0xfd, 0x48, 0x4c, 0xf5, }, 6, 0, "", "",
656"62 f2 fd 48 4c f5 \tvrcp14pd %zmm5,%zmm6",},
657{{0x62, 0xf2, 0x55, 0x0f, 0x4d, 0xf4, }, 6, 0, "", "",
658"62 f2 55 0f 4d f4 \tvrcp14ss %xmm4,%xmm5,%xmm6{%k7}",},
659{{0x62, 0xf2, 0xd5, 0x0f, 0x4d, 0xf4, }, 6, 0, "", "",
660"62 f2 d5 0f 4d f4 \tvrcp14sd %xmm4,%xmm5,%xmm6{%k7}",},
661{{0x62, 0xf2, 0x7d, 0x48, 0x4e, 0xf5, }, 6, 0, "", "",
662"62 f2 7d 48 4e f5 \tvrsqrt14ps %zmm5,%zmm6",},
663{{0x62, 0xf2, 0xfd, 0x48, 0x4e, 0xf5, }, 6, 0, "", "",
664"62 f2 fd 48 4e f5 \tvrsqrt14pd %zmm5,%zmm6",},
665{{0x62, 0xf2, 0x55, 0x0f, 0x4f, 0xf4, }, 6, 0, "", "",
666"62 f2 55 0f 4f f4 \tvrsqrt14ss %xmm4,%xmm5,%xmm6{%k7}",},
667{{0x62, 0xf2, 0xd5, 0x0f, 0x4f, 0xf4, }, 6, 0, "", "",
668"62 f2 d5 0f 4f f4 \tvrsqrt14sd %xmm4,%xmm5,%xmm6{%k7}",},
669{{0xc4, 0xe2, 0x79, 0x59, 0xf4, }, 5, 0, "", "",
670"c4 e2 79 59 f4 \tvpbroadcastq %xmm4,%xmm6",},
671{{0x62, 0xf2, 0x7d, 0x48, 0x59, 0xf7, }, 6, 0, "", "",
672"62 f2 7d 48 59 f7 \tvbroadcasti32x2 %xmm7,%zmm6",},
673{{0xc4, 0xe2, 0x7d, 0x5a, 0x21, }, 5, 0, "", "",
674"c4 e2 7d 5a 21 \tvbroadcasti128 (%ecx),%ymm4",},
675{{0x62, 0xf2, 0x7d, 0x48, 0x5a, 0x31, }, 6, 0, "", "",
676"62 f2 7d 48 5a 31 \tvbroadcasti32x4 (%ecx),%zmm6",},
677{{0x62, 0xf2, 0xfd, 0x48, 0x5a, 0x31, }, 6, 0, "", "",
678"62 f2 fd 48 5a 31 \tvbroadcasti64x2 (%ecx),%zmm6",},
679{{0x62, 0xf2, 0x7d, 0x48, 0x5b, 0x31, }, 6, 0, "", "",
680"62 f2 7d 48 5b 31 \tvbroadcasti32x8 (%ecx),%zmm6",},
681{{0x62, 0xf2, 0xfd, 0x48, 0x5b, 0x31, }, 6, 0, "", "",
682"62 f2 fd 48 5b 31 \tvbroadcasti64x4 (%ecx),%zmm6",},
683{{0x62, 0xf2, 0x55, 0x48, 0x64, 0xf4, }, 6, 0, "", "",
684"62 f2 55 48 64 f4 \tvpblendmd %zmm4,%zmm5,%zmm6",},
685{{0x62, 0xf2, 0xd5, 0x48, 0x64, 0xf4, }, 6, 0, "", "",
686"62 f2 d5 48 64 f4 \tvpblendmq %zmm4,%zmm5,%zmm6",},
687{{0x62, 0xf2, 0x55, 0x48, 0x65, 0xf4, }, 6, 0, "", "",
688"62 f2 55 48 65 f4 \tvblendmps %zmm4,%zmm5,%zmm6",},
689{{0x62, 0xf2, 0xd5, 0x48, 0x65, 0xf4, }, 6, 0, "", "",
690"62 f2 d5 48 65 f4 \tvblendmpd %zmm4,%zmm5,%zmm6",},
691{{0x62, 0xf2, 0x55, 0x48, 0x66, 0xf4, }, 6, 0, "", "",
692"62 f2 55 48 66 f4 \tvpblendmb %zmm4,%zmm5,%zmm6",},
693{{0x62, 0xf2, 0xd5, 0x48, 0x66, 0xf4, }, 6, 0, "", "",
694"62 f2 d5 48 66 f4 \tvpblendmw %zmm4,%zmm5,%zmm6",},
695{{0x62, 0xf2, 0x55, 0x48, 0x75, 0xf4, }, 6, 0, "", "",
696"62 f2 55 48 75 f4 \tvpermi2b %zmm4,%zmm5,%zmm6",},
697{{0x62, 0xf2, 0xd5, 0x48, 0x75, 0xf4, }, 6, 0, "", "",
698"62 f2 d5 48 75 f4 \tvpermi2w %zmm4,%zmm5,%zmm6",},
699{{0x62, 0xf2, 0x55, 0x48, 0x76, 0xf4, }, 6, 0, "", "",
700"62 f2 55 48 76 f4 \tvpermi2d %zmm4,%zmm5,%zmm6",},
701{{0x62, 0xf2, 0xd5, 0x48, 0x76, 0xf4, }, 6, 0, "", "",
702"62 f2 d5 48 76 f4 \tvpermi2q %zmm4,%zmm5,%zmm6",},
703{{0x62, 0xf2, 0x55, 0x48, 0x77, 0xf4, }, 6, 0, "", "",
704"62 f2 55 48 77 f4 \tvpermi2ps %zmm4,%zmm5,%zmm6",},
705{{0x62, 0xf2, 0xd5, 0x48, 0x77, 0xf4, }, 6, 0, "", "",
706"62 f2 d5 48 77 f4 \tvpermi2pd %zmm4,%zmm5,%zmm6",},
707{{0x62, 0xf2, 0x7d, 0x08, 0x7a, 0xd8, }, 6, 0, "", "",
708"62 f2 7d 08 7a d8 \tvpbroadcastb %eax,%xmm3",},
709{{0x62, 0xf2, 0x7d, 0x08, 0x7b, 0xd8, }, 6, 0, "", "",
710"62 f2 7d 08 7b d8 \tvpbroadcastw %eax,%xmm3",},
711{{0x62, 0xf2, 0x7d, 0x08, 0x7c, 0xd8, }, 6, 0, "", "",
712"62 f2 7d 08 7c d8 \tvpbroadcastd %eax,%xmm3",},
713{{0x62, 0xf2, 0x55, 0x48, 0x7d, 0xf4, }, 6, 0, "", "",
714"62 f2 55 48 7d f4 \tvpermt2b %zmm4,%zmm5,%zmm6",},
715{{0x62, 0xf2, 0xd5, 0x48, 0x7d, 0xf4, }, 6, 0, "", "",
716"62 f2 d5 48 7d f4 \tvpermt2w %zmm4,%zmm5,%zmm6",},
717{{0x62, 0xf2, 0x55, 0x48, 0x7e, 0xf4, }, 6, 0, "", "",
718"62 f2 55 48 7e f4 \tvpermt2d %zmm4,%zmm5,%zmm6",},
719{{0x62, 0xf2, 0xd5, 0x48, 0x7e, 0xf4, }, 6, 0, "", "",
720"62 f2 d5 48 7e f4 \tvpermt2q %zmm4,%zmm5,%zmm6",},
721{{0x62, 0xf2, 0x55, 0x48, 0x7f, 0xf4, }, 6, 0, "", "",
722"62 f2 55 48 7f f4 \tvpermt2ps %zmm4,%zmm5,%zmm6",},
723{{0x62, 0xf2, 0xd5, 0x48, 0x7f, 0xf4, }, 6, 0, "", "",
724"62 f2 d5 48 7f f4 \tvpermt2pd %zmm4,%zmm5,%zmm6",},
725{{0x62, 0xf2, 0xd5, 0x48, 0x83, 0xf4, }, 6, 0, "", "",
726"62 f2 d5 48 83 f4 \tvpmultishiftqb %zmm4,%zmm5,%zmm6",},
727{{0x62, 0xf2, 0x7d, 0x48, 0x88, 0x31, }, 6, 0, "", "",
728"62 f2 7d 48 88 31 \tvexpandps (%ecx),%zmm6",},
729{{0x62, 0xf2, 0xfd, 0x48, 0x88, 0x31, }, 6, 0, "", "",
730"62 f2 fd 48 88 31 \tvexpandpd (%ecx),%zmm6",},
731{{0x62, 0xf2, 0x7d, 0x48, 0x89, 0x31, }, 6, 0, "", "",
732"62 f2 7d 48 89 31 \tvpexpandd (%ecx),%zmm6",},
733{{0x62, 0xf2, 0xfd, 0x48, 0x89, 0x31, }, 6, 0, "", "",
734"62 f2 fd 48 89 31 \tvpexpandq (%ecx),%zmm6",},
735{{0x62, 0xf2, 0x7d, 0x48, 0x8a, 0x31, }, 6, 0, "", "",
736"62 f2 7d 48 8a 31 \tvcompressps %zmm6,(%ecx)",},
737{{0x62, 0xf2, 0xfd, 0x48, 0x8a, 0x31, }, 6, 0, "", "",
738"62 f2 fd 48 8a 31 \tvcompresspd %zmm6,(%ecx)",},
739{{0x62, 0xf2, 0x7d, 0x48, 0x8b, 0x31, }, 6, 0, "", "",
740"62 f2 7d 48 8b 31 \tvpcompressd %zmm6,(%ecx)",},
741{{0x62, 0xf2, 0xfd, 0x48, 0x8b, 0x31, }, 6, 0, "", "",
742"62 f2 fd 48 8b 31 \tvpcompressq %zmm6,(%ecx)",},
743{{0x62, 0xf2, 0x55, 0x48, 0x8d, 0xf4, }, 6, 0, "", "",
744"62 f2 55 48 8d f4 \tvpermb %zmm4,%zmm5,%zmm6",},
745{{0x62, 0xf2, 0xd5, 0x48, 0x8d, 0xf4, }, 6, 0, "", "",
746"62 f2 d5 48 8d f4 \tvpermw %zmm4,%zmm5,%zmm6",},
747{{0xc4, 0xe2, 0x69, 0x90, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
748"c4 e2 69 90 4c 7d 02 \tvpgatherdd %xmm2,0x2(%ebp,%xmm7,2),%xmm1",},
749{{0xc4, 0xe2, 0xe9, 0x90, 0x4c, 0x7d, 0x04, }, 7, 0, "", "",
750"c4 e2 e9 90 4c 7d 04 \tvpgatherdq %xmm2,0x4(%ebp,%xmm7,2),%xmm1",},
751{{0x62, 0xf2, 0x7d, 0x49, 0x90, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
752"62 f2 7d 49 90 b4 fd 7b 00 00 00 \tvpgatherdd 0x7b(%ebp,%zmm7,8),%zmm6{%k1}",},
753{{0x62, 0xf2, 0xfd, 0x49, 0x90, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
754"62 f2 fd 49 90 b4 fd 7b 00 00 00 \tvpgatherdq 0x7b(%ebp,%ymm7,8),%zmm6{%k1}",},
755{{0xc4, 0xe2, 0x69, 0x91, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
756"c4 e2 69 91 4c 7d 02 \tvpgatherqd %xmm2,0x2(%ebp,%xmm7,2),%xmm1",},
757{{0xc4, 0xe2, 0xe9, 0x91, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
758"c4 e2 e9 91 4c 7d 02 \tvpgatherqq %xmm2,0x2(%ebp,%xmm7,2),%xmm1",},
759{{0x62, 0xf2, 0x7d, 0x49, 0x91, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
760"62 f2 7d 49 91 b4 fd 7b 00 00 00 \tvpgatherqd 0x7b(%ebp,%zmm7,8),%ymm6{%k1}",},
761{{0x62, 0xf2, 0xfd, 0x49, 0x91, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
762"62 f2 fd 49 91 b4 fd 7b 00 00 00 \tvpgatherqq 0x7b(%ebp,%zmm7,8),%zmm6{%k1}",},
763{{0x62, 0xf2, 0x7d, 0x49, 0xa0, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
764"62 f2 7d 49 a0 b4 fd 7b 00 00 00 \tvpscatterdd %zmm6,0x7b(%ebp,%zmm7,8){%k1}",},
765{{0x62, 0xf2, 0xfd, 0x49, 0xa0, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
766"62 f2 fd 49 a0 b4 fd 7b 00 00 00 \tvpscatterdq %zmm6,0x7b(%ebp,%ymm7,8){%k1}",},
767{{0x62, 0xf2, 0x7d, 0x49, 0xa1, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
768"62 f2 7d 49 a1 b4 fd 7b 00 00 00 \tvpscatterqd %ymm6,0x7b(%ebp,%zmm7,8){%k1}",},
769{{0x62, 0xf2, 0xfd, 0x29, 0xa1, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
770"62 f2 fd 29 a1 b4 fd 7b 00 00 00 \tvpscatterqq %ymm6,0x7b(%ebp,%ymm7,8){%k1}",},
771{{0x62, 0xf2, 0x7d, 0x49, 0xa2, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
772"62 f2 7d 49 a2 b4 fd 7b 00 00 00 \tvscatterdps %zmm6,0x7b(%ebp,%zmm7,8){%k1}",},
773{{0x62, 0xf2, 0xfd, 0x49, 0xa2, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
774"62 f2 fd 49 a2 b4 fd 7b 00 00 00 \tvscatterdpd %zmm6,0x7b(%ebp,%ymm7,8){%k1}",},
775{{0x62, 0xf2, 0x7d, 0x49, 0xa3, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
776"62 f2 7d 49 a3 b4 fd 7b 00 00 00 \tvscatterqps %ymm6,0x7b(%ebp,%zmm7,8){%k1}",},
777{{0x62, 0xf2, 0xfd, 0x49, 0xa3, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
778"62 f2 fd 49 a3 b4 fd 7b 00 00 00 \tvscatterqpd %zmm6,0x7b(%ebp,%zmm7,8){%k1}",},
779{{0x62, 0xf2, 0xd5, 0x48, 0xb4, 0xf4, }, 6, 0, "", "",
780"62 f2 d5 48 b4 f4 \tvpmadd52luq %zmm4,%zmm5,%zmm6",},
781{{0x62, 0xf2, 0xd5, 0x48, 0xb5, 0xf4, }, 6, 0, "", "",
782"62 f2 d5 48 b5 f4 \tvpmadd52huq %zmm4,%zmm5,%zmm6",},
783{{0x62, 0xf2, 0x7d, 0x48, 0xc4, 0xf5, }, 6, 0, "", "",
784"62 f2 7d 48 c4 f5 \tvpconflictd %zmm5,%zmm6",},
785{{0x62, 0xf2, 0xfd, 0x48, 0xc4, 0xf5, }, 6, 0, "", "",
786"62 f2 fd 48 c4 f5 \tvpconflictq %zmm5,%zmm6",},
787{{0x62, 0xf2, 0x7d, 0x48, 0xc8, 0xfe, }, 6, 0, "", "",
788"62 f2 7d 48 c8 fe \tvexp2ps %zmm6,%zmm7",},
789{{0x62, 0xf2, 0xfd, 0x48, 0xc8, 0xfe, }, 6, 0, "", "",
790"62 f2 fd 48 c8 fe \tvexp2pd %zmm6,%zmm7",},
791{{0x62, 0xf2, 0x7d, 0x48, 0xca, 0xfe, }, 6, 0, "", "",
792"62 f2 7d 48 ca fe \tvrcp28ps %zmm6,%zmm7",},
793{{0x62, 0xf2, 0xfd, 0x48, 0xca, 0xfe, }, 6, 0, "", "",
794"62 f2 fd 48 ca fe \tvrcp28pd %zmm6,%zmm7",},
795{{0x62, 0xf2, 0x4d, 0x0f, 0xcb, 0xfd, }, 6, 0, "", "",
796"62 f2 4d 0f cb fd \tvrcp28ss %xmm5,%xmm6,%xmm7{%k7}",},
797{{0x62, 0xf2, 0xcd, 0x0f, 0xcb, 0xfd, }, 6, 0, "", "",
798"62 f2 cd 0f cb fd \tvrcp28sd %xmm5,%xmm6,%xmm7{%k7}",},
799{{0x62, 0xf2, 0x7d, 0x48, 0xcc, 0xfe, }, 6, 0, "", "",
800"62 f2 7d 48 cc fe \tvrsqrt28ps %zmm6,%zmm7",},
801{{0x62, 0xf2, 0xfd, 0x48, 0xcc, 0xfe, }, 6, 0, "", "",
802"62 f2 fd 48 cc fe \tvrsqrt28pd %zmm6,%zmm7",},
803{{0x62, 0xf2, 0x4d, 0x0f, 0xcd, 0xfd, }, 6, 0, "", "",
804"62 f2 4d 0f cd fd \tvrsqrt28ss %xmm5,%xmm6,%xmm7{%k7}",},
805{{0x62, 0xf2, 0xcd, 0x0f, 0xcd, 0xfd, }, 6, 0, "", "",
806"62 f2 cd 0f cd fd \tvrsqrt28sd %xmm5,%xmm6,%xmm7{%k7}",},
807{{0x62, 0xf3, 0x4d, 0x48, 0x03, 0xfd, 0x12, }, 7, 0, "", "",
808"62 f3 4d 48 03 fd 12 \tvalignd $0x12,%zmm5,%zmm6,%zmm7",},
809{{0x62, 0xf3, 0xcd, 0x48, 0x03, 0xfd, 0x12, }, 7, 0, "", "",
810"62 f3 cd 48 03 fd 12 \tvalignq $0x12,%zmm5,%zmm6,%zmm7",},
811{{0xc4, 0xe3, 0x7d, 0x08, 0xd6, 0x05, }, 6, 0, "", "",
812"c4 e3 7d 08 d6 05 \tvroundps $0x5,%ymm6,%ymm2",},
813{{0x62, 0xf3, 0x7d, 0x48, 0x08, 0xf5, 0x12, }, 7, 0, "", "",
814"62 f3 7d 48 08 f5 12 \tvrndscaleps $0x12,%zmm5,%zmm6",},
815{{0xc4, 0xe3, 0x7d, 0x09, 0xd6, 0x05, }, 6, 0, "", "",
816"c4 e3 7d 09 d6 05 \tvroundpd $0x5,%ymm6,%ymm2",},
817{{0x62, 0xf3, 0xfd, 0x48, 0x09, 0xf5, 0x12, }, 7, 0, "", "",
818"62 f3 fd 48 09 f5 12 \tvrndscalepd $0x12,%zmm5,%zmm6",},
819{{0xc4, 0xe3, 0x49, 0x0a, 0xd4, 0x05, }, 6, 0, "", "",
820"c4 e3 49 0a d4 05 \tvroundss $0x5,%xmm4,%xmm6,%xmm2",},
821{{0x62, 0xf3, 0x55, 0x0f, 0x0a, 0xf4, 0x12, }, 7, 0, "", "",
822"62 f3 55 0f 0a f4 12 \tvrndscaless $0x12,%xmm4,%xmm5,%xmm6{%k7}",},
823{{0xc4, 0xe3, 0x49, 0x0b, 0xd4, 0x05, }, 6, 0, "", "",
824"c4 e3 49 0b d4 05 \tvroundsd $0x5,%xmm4,%xmm6,%xmm2",},
825{{0x62, 0xf3, 0xd5, 0x0f, 0x0b, 0xf4, 0x12, }, 7, 0, "", "",
826"62 f3 d5 0f 0b f4 12 \tvrndscalesd $0x12,%xmm4,%xmm5,%xmm6{%k7}",},
827{{0xc4, 0xe3, 0x5d, 0x18, 0xf4, 0x05, }, 6, 0, "", "",
828"c4 e3 5d 18 f4 05 \tvinsertf128 $0x5,%xmm4,%ymm4,%ymm6",},
829{{0x62, 0xf3, 0x55, 0x4f, 0x18, 0xf4, 0x12, }, 7, 0, "", "",
830"62 f3 55 4f 18 f4 12 \tvinsertf32x4 $0x12,%xmm4,%zmm5,%zmm6{%k7}",},
831{{0x62, 0xf3, 0xd5, 0x4f, 0x18, 0xf4, 0x12, }, 7, 0, "", "",
832"62 f3 d5 4f 18 f4 12 \tvinsertf64x2 $0x12,%xmm4,%zmm5,%zmm6{%k7}",},
833{{0xc4, 0xe3, 0x7d, 0x19, 0xe4, 0x05, }, 6, 0, "", "",
834"c4 e3 7d 19 e4 05 \tvextractf128 $0x5,%ymm4,%xmm4",},
835{{0x62, 0xf3, 0x7d, 0x4f, 0x19, 0xee, 0x12, }, 7, 0, "", "",
836"62 f3 7d 4f 19 ee 12 \tvextractf32x4 $0x12,%zmm5,%xmm6{%k7}",},
837{{0x62, 0xf3, 0xfd, 0x4f, 0x19, 0xee, 0x12, }, 7, 0, "", "",
838"62 f3 fd 4f 19 ee 12 \tvextractf64x2 $0x12,%zmm5,%xmm6{%k7}",},
839{{0x62, 0xf3, 0x4d, 0x4f, 0x1a, 0xfd, 0x12, }, 7, 0, "", "",
840"62 f3 4d 4f 1a fd 12 \tvinsertf32x8 $0x12,%ymm5,%zmm6,%zmm7{%k7}",},
841{{0x62, 0xf3, 0xcd, 0x4f, 0x1a, 0xfd, 0x12, }, 7, 0, "", "",
842"62 f3 cd 4f 1a fd 12 \tvinsertf64x4 $0x12,%ymm5,%zmm6,%zmm7{%k7}",},
843{{0x62, 0xf3, 0x7d, 0x4f, 0x1b, 0xf7, 0x12, }, 7, 0, "", "",
844"62 f3 7d 4f 1b f7 12 \tvextractf32x8 $0x12,%zmm6,%ymm7{%k7}",},
845{{0x62, 0xf3, 0xfd, 0x4f, 0x1b, 0xf7, 0x12, }, 7, 0, "", "",
846"62 f3 fd 4f 1b f7 12 \tvextractf64x4 $0x12,%zmm6,%ymm7{%k7}",},
847{{0x62, 0xf3, 0x45, 0x48, 0x1e, 0xee, 0x12, }, 7, 0, "", "",
848"62 f3 45 48 1e ee 12 \tvpcmpud $0x12,%zmm6,%zmm7,%k5",},
849{{0x62, 0xf3, 0xc5, 0x48, 0x1e, 0xee, 0x12, }, 7, 0, "", "",
850"62 f3 c5 48 1e ee 12 \tvpcmpuq $0x12,%zmm6,%zmm7,%k5",},
851{{0x62, 0xf3, 0x45, 0x48, 0x1f, 0xee, 0x12, }, 7, 0, "", "",
852"62 f3 45 48 1f ee 12 \tvpcmpd $0x12,%zmm6,%zmm7,%k5",},
853{{0x62, 0xf3, 0xc5, 0x48, 0x1f, 0xee, 0x12, }, 7, 0, "", "",
854"62 f3 c5 48 1f ee 12 \tvpcmpq $0x12,%zmm6,%zmm7,%k5",},
855{{0x62, 0xf3, 0x4d, 0x48, 0x23, 0xfd, 0x12, }, 7, 0, "", "",
856"62 f3 4d 48 23 fd 12 \tvshuff32x4 $0x12,%zmm5,%zmm6,%zmm7",},
857{{0x62, 0xf3, 0xcd, 0x48, 0x23, 0xfd, 0x12, }, 7, 0, "", "",
858"62 f3 cd 48 23 fd 12 \tvshuff64x2 $0x12,%zmm5,%zmm6,%zmm7",},
859{{0x62, 0xf3, 0x4d, 0x48, 0x25, 0xfd, 0x12, }, 7, 0, "", "",
860"62 f3 4d 48 25 fd 12 \tvpternlogd $0x12,%zmm5,%zmm6,%zmm7",},
861{{0x62, 0xf3, 0xcd, 0x48, 0x25, 0xfd, 0x12, }, 7, 0, "", "",
862"62 f3 cd 48 25 fd 12 \tvpternlogq $0x12,%zmm5,%zmm6,%zmm7",},
863{{0x62, 0xf3, 0x7d, 0x48, 0x26, 0xfe, 0x12, }, 7, 0, "", "",
864"62 f3 7d 48 26 fe 12 \tvgetmantps $0x12,%zmm6,%zmm7",},
865{{0x62, 0xf3, 0xfd, 0x48, 0x26, 0xfe, 0x12, }, 7, 0, "", "",
866"62 f3 fd 48 26 fe 12 \tvgetmantpd $0x12,%zmm6,%zmm7",},
867{{0x62, 0xf3, 0x4d, 0x0f, 0x27, 0xfd, 0x12, }, 7, 0, "", "",
868"62 f3 4d 0f 27 fd 12 \tvgetmantss $0x12,%xmm5,%xmm6,%xmm7{%k7}",},
869{{0x62, 0xf3, 0xcd, 0x0f, 0x27, 0xfd, 0x12, }, 7, 0, "", "",
870"62 f3 cd 0f 27 fd 12 \tvgetmantsd $0x12,%xmm5,%xmm6,%xmm7{%k7}",},
871{{0xc4, 0xe3, 0x5d, 0x38, 0xf4, 0x05, }, 6, 0, "", "",
872"c4 e3 5d 38 f4 05 \tvinserti128 $0x5,%xmm4,%ymm4,%ymm6",},
873{{0x62, 0xf3, 0x55, 0x4f, 0x38, 0xf4, 0x12, }, 7, 0, "", "",
874"62 f3 55 4f 38 f4 12 \tvinserti32x4 $0x12,%xmm4,%zmm5,%zmm6{%k7}",},
875{{0x62, 0xf3, 0xd5, 0x4f, 0x38, 0xf4, 0x12, }, 7, 0, "", "",
876"62 f3 d5 4f 38 f4 12 \tvinserti64x2 $0x12,%xmm4,%zmm5,%zmm6{%k7}",},
877{{0xc4, 0xe3, 0x7d, 0x39, 0xe6, 0x05, }, 6, 0, "", "",
878"c4 e3 7d 39 e6 05 \tvextracti128 $0x5,%ymm4,%xmm6",},
879{{0x62, 0xf3, 0x7d, 0x4f, 0x39, 0xee, 0x12, }, 7, 0, "", "",
880"62 f3 7d 4f 39 ee 12 \tvextracti32x4 $0x12,%zmm5,%xmm6{%k7}",},
881{{0x62, 0xf3, 0xfd, 0x4f, 0x39, 0xee, 0x12, }, 7, 0, "", "",
882"62 f3 fd 4f 39 ee 12 \tvextracti64x2 $0x12,%zmm5,%xmm6{%k7}",},
883{{0x62, 0xf3, 0x4d, 0x4f, 0x3a, 0xfd, 0x12, }, 7, 0, "", "",
884"62 f3 4d 4f 3a fd 12 \tvinserti32x8 $0x12,%ymm5,%zmm6,%zmm7{%k7}",},
885{{0x62, 0xf3, 0xcd, 0x4f, 0x3a, 0xfd, 0x12, }, 7, 0, "", "",
886"62 f3 cd 4f 3a fd 12 \tvinserti64x4 $0x12,%ymm5,%zmm6,%zmm7{%k7}",},
887{{0x62, 0xf3, 0x7d, 0x4f, 0x3b, 0xf7, 0x12, }, 7, 0, "", "",
888"62 f3 7d 4f 3b f7 12 \tvextracti32x8 $0x12,%zmm6,%ymm7{%k7}",},
889{{0x62, 0xf3, 0xfd, 0x4f, 0x3b, 0xf7, 0x12, }, 7, 0, "", "",
890"62 f3 fd 4f 3b f7 12 \tvextracti64x4 $0x12,%zmm6,%ymm7{%k7}",},
891{{0x62, 0xf3, 0x45, 0x48, 0x3e, 0xee, 0x12, }, 7, 0, "", "",
892"62 f3 45 48 3e ee 12 \tvpcmpub $0x12,%zmm6,%zmm7,%k5",},
893{{0x62, 0xf3, 0xc5, 0x48, 0x3e, 0xee, 0x12, }, 7, 0, "", "",
894"62 f3 c5 48 3e ee 12 \tvpcmpuw $0x12,%zmm6,%zmm7,%k5",},
895{{0x62, 0xf3, 0x45, 0x48, 0x3f, 0xee, 0x12, }, 7, 0, "", "",
896"62 f3 45 48 3f ee 12 \tvpcmpb $0x12,%zmm6,%zmm7,%k5",},
897{{0x62, 0xf3, 0xc5, 0x48, 0x3f, 0xee, 0x12, }, 7, 0, "", "",
898"62 f3 c5 48 3f ee 12 \tvpcmpw $0x12,%zmm6,%zmm7,%k5",},
899{{0xc4, 0xe3, 0x4d, 0x42, 0xd4, 0x05, }, 6, 0, "", "",
900"c4 e3 4d 42 d4 05 \tvmpsadbw $0x5,%ymm4,%ymm6,%ymm2",},
901{{0x62, 0xf3, 0x55, 0x48, 0x42, 0xf4, 0x12, }, 7, 0, "", "",
902"62 f3 55 48 42 f4 12 \tvdbpsadbw $0x12,%zmm4,%zmm5,%zmm6",},
903{{0x62, 0xf3, 0x4d, 0x48, 0x43, 0xfd, 0x12, }, 7, 0, "", "",
904"62 f3 4d 48 43 fd 12 \tvshufi32x4 $0x12,%zmm5,%zmm6,%zmm7",},
905{{0x62, 0xf3, 0xcd, 0x48, 0x43, 0xfd, 0x12, }, 7, 0, "", "",
906"62 f3 cd 48 43 fd 12 \tvshufi64x2 $0x12,%zmm5,%zmm6,%zmm7",},
907{{0x62, 0xf3, 0x4d, 0x48, 0x50, 0xfd, 0x12, }, 7, 0, "", "",
908"62 f3 4d 48 50 fd 12 \tvrangeps $0x12,%zmm5,%zmm6,%zmm7",},
909{{0x62, 0xf3, 0xcd, 0x48, 0x50, 0xfd, 0x12, }, 7, 0, "", "",
910"62 f3 cd 48 50 fd 12 \tvrangepd $0x12,%zmm5,%zmm6,%zmm7",},
911{{0x62, 0xf3, 0x4d, 0x08, 0x51, 0xfd, 0x12, }, 7, 0, "", "",
912"62 f3 4d 08 51 fd 12 \tvrangess $0x12,%xmm5,%xmm6,%xmm7",},
913{{0x62, 0xf3, 0xcd, 0x08, 0x51, 0xfd, 0x12, }, 7, 0, "", "",
914"62 f3 cd 08 51 fd 12 \tvrangesd $0x12,%xmm5,%xmm6,%xmm7",},
915{{0x62, 0xf3, 0x4d, 0x48, 0x54, 0xfd, 0x12, }, 7, 0, "", "",
916"62 f3 4d 48 54 fd 12 \tvfixupimmps $0x12,%zmm5,%zmm6,%zmm7",},
917{{0x62, 0xf3, 0xcd, 0x48, 0x54, 0xfd, 0x12, }, 7, 0, "", "",
918"62 f3 cd 48 54 fd 12 \tvfixupimmpd $0x12,%zmm5,%zmm6,%zmm7",},
919{{0x62, 0xf3, 0x4d, 0x0f, 0x55, 0xfd, 0x12, }, 7, 0, "", "",
920"62 f3 4d 0f 55 fd 12 \tvfixupimmss $0x12,%xmm5,%xmm6,%xmm7{%k7}",},
921{{0x62, 0xf3, 0xcd, 0x0f, 0x55, 0xfd, 0x12, }, 7, 0, "", "",
922"62 f3 cd 0f 55 fd 12 \tvfixupimmsd $0x12,%xmm5,%xmm6,%xmm7{%k7}",},
923{{0x62, 0xf3, 0x7d, 0x48, 0x56, 0xfe, 0x12, }, 7, 0, "", "",
924"62 f3 7d 48 56 fe 12 \tvreduceps $0x12,%zmm6,%zmm7",},
925{{0x62, 0xf3, 0xfd, 0x48, 0x56, 0xfe, 0x12, }, 7, 0, "", "",
926"62 f3 fd 48 56 fe 12 \tvreducepd $0x12,%zmm6,%zmm7",},
927{{0x62, 0xf3, 0x4d, 0x08, 0x57, 0xfd, 0x12, }, 7, 0, "", "",
928"62 f3 4d 08 57 fd 12 \tvreducess $0x12,%xmm5,%xmm6,%xmm7",},
929{{0x62, 0xf3, 0xcd, 0x08, 0x57, 0xfd, 0x12, }, 7, 0, "", "",
930"62 f3 cd 08 57 fd 12 \tvreducesd $0x12,%xmm5,%xmm6,%xmm7",},
931{{0x62, 0xf3, 0x7d, 0x48, 0x66, 0xef, 0x12, }, 7, 0, "", "",
932"62 f3 7d 48 66 ef 12 \tvfpclassps $0x12,%zmm7,%k5",},
933{{0x62, 0xf3, 0xfd, 0x48, 0x66, 0xef, 0x12, }, 7, 0, "", "",
934"62 f3 fd 48 66 ef 12 \tvfpclasspd $0x12,%zmm7,%k5",},
935{{0x62, 0xf3, 0x7d, 0x08, 0x67, 0xef, 0x12, }, 7, 0, "", "",
936"62 f3 7d 08 67 ef 12 \tvfpclassss $0x12,%xmm7,%k5",},
937{{0x62, 0xf3, 0xfd, 0x08, 0x67, 0xef, 0x12, }, 7, 0, "", "",
938"62 f3 fd 08 67 ef 12 \tvfpclasssd $0x12,%xmm7,%k5",},
939{{0x62, 0xf1, 0x4d, 0x48, 0x72, 0xc5, 0x12, }, 7, 0, "", "",
940"62 f1 4d 48 72 c5 12 \tvprord $0x12,%zmm5,%zmm6",},
941{{0x62, 0xf1, 0xcd, 0x48, 0x72, 0xc5, 0x12, }, 7, 0, "", "",
942"62 f1 cd 48 72 c5 12 \tvprorq $0x12,%zmm5,%zmm6",},
943{{0x62, 0xf1, 0x4d, 0x48, 0x72, 0xcd, 0x12, }, 7, 0, "", "",
944"62 f1 4d 48 72 cd 12 \tvprold $0x12,%zmm5,%zmm6",},
945{{0x62, 0xf1, 0xcd, 0x48, 0x72, 0xcd, 0x12, }, 7, 0, "", "",
946"62 f1 cd 48 72 cd 12 \tvprolq $0x12,%zmm5,%zmm6",},
947{{0x0f, 0x72, 0xe6, 0x02, }, 4, 0, "", "",
948"0f 72 e6 02 \tpsrad $0x2,%mm6",},
949{{0xc5, 0xed, 0x72, 0xe6, 0x05, }, 5, 0, "", "",
950"c5 ed 72 e6 05 \tvpsrad $0x5,%ymm6,%ymm2",},
951{{0x62, 0xf1, 0x6d, 0x48, 0x72, 0xe6, 0x05, }, 7, 0, "", "",
952"62 f1 6d 48 72 e6 05 \tvpsrad $0x5,%zmm6,%zmm2",},
953{{0x62, 0xf1, 0xed, 0x48, 0x72, 0xe6, 0x05, }, 7, 0, "", "",
954"62 f1 ed 48 72 e6 05 \tvpsraq $0x5,%zmm6,%zmm2",},
955{{0x62, 0xf2, 0x7d, 0x49, 0xc6, 0x8c, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
956"62 f2 7d 49 c6 8c fd 7b 00 00 00 \tvgatherpf0dps 0x7b(%ebp,%zmm7,8){%k1}",},
957{{0x62, 0xf2, 0xfd, 0x49, 0xc6, 0x8c, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
958"62 f2 fd 49 c6 8c fd 7b 00 00 00 \tvgatherpf0dpd 0x7b(%ebp,%ymm7,8){%k1}",},
959{{0x62, 0xf2, 0x7d, 0x49, 0xc6, 0x94, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
960"62 f2 7d 49 c6 94 fd 7b 00 00 00 \tvgatherpf1dps 0x7b(%ebp,%zmm7,8){%k1}",},
961{{0x62, 0xf2, 0xfd, 0x49, 0xc6, 0x94, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
962"62 f2 fd 49 c6 94 fd 7b 00 00 00 \tvgatherpf1dpd 0x7b(%ebp,%ymm7,8){%k1}",},
963{{0x62, 0xf2, 0x7d, 0x49, 0xc6, 0xac, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
964"62 f2 7d 49 c6 ac fd 7b 00 00 00 \tvscatterpf0dps 0x7b(%ebp,%zmm7,8){%k1}",},
965{{0x62, 0xf2, 0xfd, 0x49, 0xc6, 0xac, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
966"62 f2 fd 49 c6 ac fd 7b 00 00 00 \tvscatterpf0dpd 0x7b(%ebp,%ymm7,8){%k1}",},
967{{0x62, 0xf2, 0x7d, 0x49, 0xc6, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
968"62 f2 7d 49 c6 b4 fd 7b 00 00 00 \tvscatterpf1dps 0x7b(%ebp,%zmm7,8){%k1}",},
969{{0x62, 0xf2, 0xfd, 0x49, 0xc6, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
970"62 f2 fd 49 c6 b4 fd 7b 00 00 00 \tvscatterpf1dpd 0x7b(%ebp,%ymm7,8){%k1}",},
971{{0x62, 0xf2, 0x7d, 0x49, 0xc7, 0x8c, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
972"62 f2 7d 49 c7 8c fd 7b 00 00 00 \tvgatherpf0qps 0x7b(%ebp,%zmm7,8){%k1}",},
973{{0x62, 0xf2, 0xfd, 0x49, 0xc7, 0x8c, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
974"62 f2 fd 49 c7 8c fd 7b 00 00 00 \tvgatherpf0qpd 0x7b(%ebp,%zmm7,8){%k1}",},
975{{0x62, 0xf2, 0x7d, 0x49, 0xc7, 0x94, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
976"62 f2 7d 49 c7 94 fd 7b 00 00 00 \tvgatherpf1qps 0x7b(%ebp,%zmm7,8){%k1}",},
977{{0x62, 0xf2, 0xfd, 0x49, 0xc7, 0x94, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
978"62 f2 fd 49 c7 94 fd 7b 00 00 00 \tvgatherpf1qpd 0x7b(%ebp,%zmm7,8){%k1}",},
979{{0x62, 0xf2, 0x7d, 0x49, 0xc7, 0xac, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
980"62 f2 7d 49 c7 ac fd 7b 00 00 00 \tvscatterpf0qps 0x7b(%ebp,%zmm7,8){%k1}",},
981{{0x62, 0xf2, 0xfd, 0x49, 0xc7, 0xac, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
982"62 f2 fd 49 c7 ac fd 7b 00 00 00 \tvscatterpf0qpd 0x7b(%ebp,%zmm7,8){%k1}",},
983{{0x62, 0xf2, 0x7d, 0x49, 0xc7, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
984"62 f2 7d 49 c7 b4 fd 7b 00 00 00 \tvscatterpf1qps 0x7b(%ebp,%zmm7,8){%k1}",},
985{{0x62, 0xf2, 0xfd, 0x49, 0xc7, 0xb4, 0xfd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
986"62 f2 fd 49 c7 b4 fd 7b 00 00 00 \tvscatterpf1qpd 0x7b(%ebp,%zmm7,8){%k1}",},
987{{0x62, 0xf1, 0xd5, 0x48, 0x58, 0xf4, }, 6, 0, "", "",
988"62 f1 d5 48 58 f4 \tvaddpd %zmm4,%zmm5,%zmm6",},
989{{0x62, 0xf1, 0xd5, 0x4f, 0x58, 0xf4, }, 6, 0, "", "",
990"62 f1 d5 4f 58 f4 \tvaddpd %zmm4,%zmm5,%zmm6{%k7}",},
991{{0x62, 0xf1, 0xd5, 0xcf, 0x58, 0xf4, }, 6, 0, "", "",
992"62 f1 d5 cf 58 f4 \tvaddpd %zmm4,%zmm5,%zmm6{%k7}{z}",},
993{{0x62, 0xf1, 0xd5, 0x18, 0x58, 0xf4, }, 6, 0, "", "",
994"62 f1 d5 18 58 f4 \tvaddpd {rn-sae},%zmm4,%zmm5,%zmm6",},
995{{0x62, 0xf1, 0xd5, 0x58, 0x58, 0xf4, }, 6, 0, "", "",
996"62 f1 d5 58 58 f4 \tvaddpd {ru-sae},%zmm4,%zmm5,%zmm6",},
997{{0x62, 0xf1, 0xd5, 0x38, 0x58, 0xf4, }, 6, 0, "", "",
998"62 f1 d5 38 58 f4 \tvaddpd {rd-sae},%zmm4,%zmm5,%zmm6",},
999{{0x62, 0xf1, 0xd5, 0x78, 0x58, 0xf4, }, 6, 0, "", "",
1000"62 f1 d5 78 58 f4 \tvaddpd {rz-sae},%zmm4,%zmm5,%zmm6",},
1001{{0x62, 0xf1, 0xd5, 0x48, 0x58, 0x31, }, 6, 0, "", "",
1002"62 f1 d5 48 58 31 \tvaddpd (%ecx),%zmm5,%zmm6",},
1003{{0x62, 0xf1, 0xd5, 0x48, 0x58, 0xb4, 0xc8, 0x23, 0x01, 0x00, 0x00, }, 11, 0, "", "",
1004"62 f1 d5 48 58 b4 c8 23 01 00 00 \tvaddpd 0x123(%eax,%ecx,8),%zmm5,%zmm6",},
1005{{0x62, 0xf1, 0xd5, 0x58, 0x58, 0x31, }, 6, 0, "", "",
1006"62 f1 d5 58 58 31 \tvaddpd (%ecx){1to8},%zmm5,%zmm6",},
1007{{0x62, 0xf1, 0xd5, 0x48, 0x58, 0x72, 0x7f, }, 7, 0, "", "",
1008"62 f1 d5 48 58 72 7f \tvaddpd 0x1fc0(%edx),%zmm5,%zmm6",},
1009{{0x62, 0xf1, 0xd5, 0x58, 0x58, 0x72, 0x7f, }, 7, 0, "", "",
1010"62 f1 d5 58 58 72 7f \tvaddpd 0x3f8(%edx){1to8},%zmm5,%zmm6",},
1011{{0x62, 0xf1, 0x4c, 0x58, 0xc2, 0x6a, 0x7f, 0x08, }, 8, 0, "", "",
1012"62 f1 4c 58 c2 6a 7f 08 \tvcmpeq_uqps 0x1fc(%edx){1to16},%zmm6,%k5",},
1013{{0x62, 0xf1, 0xe7, 0x0f, 0xc2, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, 0x01, }, 12, 0, "", "",
1014"62 f1 e7 0f c2 ac c8 23 01 00 00 01 \tvcmpltsd 0x123(%eax,%ecx,8),%xmm3,%k5{%k7}",},
1015{{0x62, 0xf1, 0xd7, 0x1f, 0xc2, 0xec, 0x02, }, 7, 0, "", "",
1016"62 f1 d7 1f c2 ec 02 \tvcmplesd {sae},%xmm4,%xmm5,%k5{%k7}",},
1017{{0x62, 0xf3, 0x5d, 0x0f, 0x27, 0xac, 0xc8, 0x23, 0x01, 0x00, 0x00, 0x5b, }, 12, 0, "", "",
1018"62 f3 5d 0f 27 ac c8 23 01 00 00 5b \tvgetmantss $0x5b,0x123(%eax,%ecx,8),%xmm4,%xmm5{%k7}",},
9{{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "", 1019{{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
10"f3 0f 1b 00 \tbndmk (%eax),%bnd0",}, 1020"f3 0f 1b 00 \tbndmk (%eax),%bnd0",},
11{{0xf3, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "", 1021{{0xf3, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
@@ -309,19 +1319,19 @@
309{{0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "", 1319{{0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
310"0f 1b 84 08 78 56 34 12 \tbndstx %bnd0,0x12345678(%eax,%ecx,1)",}, 1320"0f 1b 84 08 78 56 34 12 \tbndstx %bnd0,0x12345678(%eax,%ecx,1)",},
311{{0xf2, 0xe8, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "call", "unconditional", 1321{{0xf2, 0xe8, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "call", "unconditional",
312"f2 e8 fc ff ff ff \tbnd call 3c3 <main+0x3c3>",}, 1322"f2 e8 fc ff ff ff \tbnd call fce <main+0xfce>",},
313{{0xf2, 0xff, 0x10, }, 3, 0, "call", "indirect", 1323{{0xf2, 0xff, 0x10, }, 3, 0, "call", "indirect",
314"f2 ff 10 \tbnd call *(%eax)",}, 1324"f2 ff 10 \tbnd call *(%eax)",},
315{{0xf2, 0xc3, }, 2, 0, "ret", "indirect", 1325{{0xf2, 0xc3, }, 2, 0, "ret", "indirect",
316"f2 c3 \tbnd ret ",}, 1326"f2 c3 \tbnd ret ",},
317{{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional", 1327{{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional",
318"f2 e9 fc ff ff ff \tbnd jmp 3ce <main+0x3ce>",}, 1328"f2 e9 fc ff ff ff \tbnd jmp fd9 <main+0xfd9>",},
319{{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional", 1329{{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional",
320"f2 e9 fc ff ff ff \tbnd jmp 3d4 <main+0x3d4>",}, 1330"f2 e9 fc ff ff ff \tbnd jmp fdf <main+0xfdf>",},
321{{0xf2, 0xff, 0x21, }, 3, 0, "jmp", "indirect", 1331{{0xf2, 0xff, 0x21, }, 3, 0, "jmp", "indirect",
322"f2 ff 21 \tbnd jmp *(%ecx)",}, 1332"f2 ff 21 \tbnd jmp *(%ecx)",},
323{{0xf2, 0x0f, 0x85, 0xfc, 0xff, 0xff, 0xff, }, 7, 0xfffffffc, "jcc", "conditional", 1333{{0xf2, 0x0f, 0x85, 0xfc, 0xff, 0xff, 0xff, }, 7, 0xfffffffc, "jcc", "conditional",
324"f2 0f 85 fc ff ff ff \tbnd jne 3de <main+0x3de>",}, 1334"f2 0f 85 fc ff ff ff \tbnd jne fe9 <main+0xfe9>",},
325{{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "", 1335{{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "",
326"0f 3a cc c1 00 \tsha1rnds4 $0x0,%xmm1,%xmm0",}, 1336"0f 3a cc c1 00 \tsha1rnds4 $0x0,%xmm1,%xmm0",},
327{{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "", 1337{{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "",
@@ -654,5 +1664,3 @@
654"0f c7 1d 78 56 34 12 \txrstors 0x12345678",}, 1664"0f c7 1d 78 56 34 12 \txrstors 0x12345678",},
655{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "", 1665{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
656"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%eax,%ecx,8)",}, 1666"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%eax,%ecx,8)",},
657{{0x66, 0x0f, 0xae, 0xf8, }, 4, 0, "", "",
658"66 0f ae f8 \tpcommit ",},
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-64.c b/tools/perf/arch/x86/tests/insn-x86-dat-64.c
index 4fe7cce179c4..af25bc8240d0 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-64.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-64.c
@@ -6,6 +6,938 @@
6 6
7{{0x0f, 0x31, }, 2, 0, "", "", 7{{0x0f, 0x31, }, 2, 0, "", "",
8"0f 31 \trdtsc ",}, 8"0f 31 \trdtsc ",},
9{{0xc4, 0xe2, 0x7d, 0x13, 0xeb, }, 5, 0, "", "",
10"c4 e2 7d 13 eb \tvcvtph2ps %xmm3,%ymm5",},
11{{0x48, 0x0f, 0x41, 0xd8, }, 4, 0, "", "",
12"48 0f 41 d8 \tcmovno %rax,%rbx",},
13{{0x48, 0x0f, 0x41, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
14"48 0f 41 88 78 56 34 12 \tcmovno 0x12345678(%rax),%rcx",},
15{{0x66, 0x0f, 0x41, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
16"66 0f 41 88 78 56 34 12 \tcmovno 0x12345678(%rax),%cx",},
17{{0x48, 0x0f, 0x44, 0xd8, }, 4, 0, "", "",
18"48 0f 44 d8 \tcmove %rax,%rbx",},
19{{0x48, 0x0f, 0x44, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
20"48 0f 44 88 78 56 34 12 \tcmove 0x12345678(%rax),%rcx",},
21{{0x66, 0x0f, 0x44, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
22"66 0f 44 88 78 56 34 12 \tcmove 0x12345678(%rax),%cx",},
23{{0x0f, 0x90, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
24"0f 90 80 78 56 34 12 \tseto 0x12345678(%rax)",},
25{{0x0f, 0x91, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
26"0f 91 80 78 56 34 12 \tsetno 0x12345678(%rax)",},
27{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
28"0f 92 80 78 56 34 12 \tsetb 0x12345678(%rax)",},
29{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
30"0f 92 80 78 56 34 12 \tsetb 0x12345678(%rax)",},
31{{0x0f, 0x92, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
32"0f 92 80 78 56 34 12 \tsetb 0x12345678(%rax)",},
33{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
34"0f 93 80 78 56 34 12 \tsetae 0x12345678(%rax)",},
35{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
36"0f 93 80 78 56 34 12 \tsetae 0x12345678(%rax)",},
37{{0x0f, 0x93, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
38"0f 93 80 78 56 34 12 \tsetae 0x12345678(%rax)",},
39{{0x0f, 0x98, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
40"0f 98 80 78 56 34 12 \tsets 0x12345678(%rax)",},
41{{0x0f, 0x99, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
42"0f 99 80 78 56 34 12 \tsetns 0x12345678(%rax)",},
43{{0xc5, 0xcc, 0x41, 0xef, }, 4, 0, "", "",
44"c5 cc 41 ef \tkandw %k7,%k6,%k5",},
45{{0xc4, 0xe1, 0xcc, 0x41, 0xef, }, 5, 0, "", "",
46"c4 e1 cc 41 ef \tkandq %k7,%k6,%k5",},
47{{0xc5, 0xcd, 0x41, 0xef, }, 4, 0, "", "",
48"c5 cd 41 ef \tkandb %k7,%k6,%k5",},
49{{0xc4, 0xe1, 0xcd, 0x41, 0xef, }, 5, 0, "", "",
50"c4 e1 cd 41 ef \tkandd %k7,%k6,%k5",},
51{{0xc5, 0xcc, 0x42, 0xef, }, 4, 0, "", "",
52"c5 cc 42 ef \tkandnw %k7,%k6,%k5",},
53{{0xc4, 0xe1, 0xcc, 0x42, 0xef, }, 5, 0, "", "",
54"c4 e1 cc 42 ef \tkandnq %k7,%k6,%k5",},
55{{0xc5, 0xcd, 0x42, 0xef, }, 4, 0, "", "",
56"c5 cd 42 ef \tkandnb %k7,%k6,%k5",},
57{{0xc4, 0xe1, 0xcd, 0x42, 0xef, }, 5, 0, "", "",
58"c4 e1 cd 42 ef \tkandnd %k7,%k6,%k5",},
59{{0xc5, 0xf8, 0x44, 0xf7, }, 4, 0, "", "",
60"c5 f8 44 f7 \tknotw %k7,%k6",},
61{{0xc4, 0xe1, 0xf8, 0x44, 0xf7, }, 5, 0, "", "",
62"c4 e1 f8 44 f7 \tknotq %k7,%k6",},
63{{0xc5, 0xf9, 0x44, 0xf7, }, 4, 0, "", "",
64"c5 f9 44 f7 \tknotb %k7,%k6",},
65{{0xc4, 0xe1, 0xf9, 0x44, 0xf7, }, 5, 0, "", "",
66"c4 e1 f9 44 f7 \tknotd %k7,%k6",},
67{{0xc5, 0xcc, 0x45, 0xef, }, 4, 0, "", "",
68"c5 cc 45 ef \tkorw %k7,%k6,%k5",},
69{{0xc4, 0xe1, 0xcc, 0x45, 0xef, }, 5, 0, "", "",
70"c4 e1 cc 45 ef \tkorq %k7,%k6,%k5",},
71{{0xc5, 0xcd, 0x45, 0xef, }, 4, 0, "", "",
72"c5 cd 45 ef \tkorb %k7,%k6,%k5",},
73{{0xc4, 0xe1, 0xcd, 0x45, 0xef, }, 5, 0, "", "",
74"c4 e1 cd 45 ef \tkord %k7,%k6,%k5",},
75{{0xc5, 0xcc, 0x46, 0xef, }, 4, 0, "", "",
76"c5 cc 46 ef \tkxnorw %k7,%k6,%k5",},
77{{0xc4, 0xe1, 0xcc, 0x46, 0xef, }, 5, 0, "", "",
78"c4 e1 cc 46 ef \tkxnorq %k7,%k6,%k5",},
79{{0xc5, 0xcd, 0x46, 0xef, }, 4, 0, "", "",
80"c5 cd 46 ef \tkxnorb %k7,%k6,%k5",},
81{{0xc4, 0xe1, 0xcd, 0x46, 0xef, }, 5, 0, "", "",
82"c4 e1 cd 46 ef \tkxnord %k7,%k6,%k5",},
83{{0xc5, 0xcc, 0x47, 0xef, }, 4, 0, "", "",
84"c5 cc 47 ef \tkxorw %k7,%k6,%k5",},
85{{0xc4, 0xe1, 0xcc, 0x47, 0xef, }, 5, 0, "", "",
86"c4 e1 cc 47 ef \tkxorq %k7,%k6,%k5",},
87{{0xc5, 0xcd, 0x47, 0xef, }, 4, 0, "", "",
88"c5 cd 47 ef \tkxorb %k7,%k6,%k5",},
89{{0xc4, 0xe1, 0xcd, 0x47, 0xef, }, 5, 0, "", "",
90"c4 e1 cd 47 ef \tkxord %k7,%k6,%k5",},
91{{0xc5, 0xcc, 0x4a, 0xef, }, 4, 0, "", "",
92"c5 cc 4a ef \tkaddw %k7,%k6,%k5",},
93{{0xc4, 0xe1, 0xcc, 0x4a, 0xef, }, 5, 0, "", "",
94"c4 e1 cc 4a ef \tkaddq %k7,%k6,%k5",},
95{{0xc5, 0xcd, 0x4a, 0xef, }, 4, 0, "", "",
96"c5 cd 4a ef \tkaddb %k7,%k6,%k5",},
97{{0xc4, 0xe1, 0xcd, 0x4a, 0xef, }, 5, 0, "", "",
98"c4 e1 cd 4a ef \tkaddd %k7,%k6,%k5",},
99{{0xc5, 0xcd, 0x4b, 0xef, }, 4, 0, "", "",
100"c5 cd 4b ef \tkunpckbw %k7,%k6,%k5",},
101{{0xc5, 0xcc, 0x4b, 0xef, }, 4, 0, "", "",
102"c5 cc 4b ef \tkunpckwd %k7,%k6,%k5",},
103{{0xc4, 0xe1, 0xcc, 0x4b, 0xef, }, 5, 0, "", "",
104"c4 e1 cc 4b ef \tkunpckdq %k7,%k6,%k5",},
105{{0xc5, 0xf8, 0x90, 0xee, }, 4, 0, "", "",
106"c5 f8 90 ee \tkmovw %k6,%k5",},
107{{0xc5, 0xf8, 0x90, 0x29, }, 4, 0, "", "",
108"c5 f8 90 29 \tkmovw (%rcx),%k5",},
109{{0xc4, 0xa1, 0x78, 0x90, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
110"c4 a1 78 90 ac f0 23 01 00 00 \tkmovw 0x123(%rax,%r14,8),%k5",},
111{{0xc5, 0xf8, 0x91, 0x29, }, 4, 0, "", "",
112"c5 f8 91 29 \tkmovw %k5,(%rcx)",},
113{{0xc4, 0xa1, 0x78, 0x91, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
114"c4 a1 78 91 ac f0 23 01 00 00 \tkmovw %k5,0x123(%rax,%r14,8)",},
115{{0xc5, 0xf8, 0x92, 0xe8, }, 4, 0, "", "",
116"c5 f8 92 e8 \tkmovw %eax,%k5",},
117{{0xc5, 0xf8, 0x92, 0xed, }, 4, 0, "", "",
118"c5 f8 92 ed \tkmovw %ebp,%k5",},
119{{0xc4, 0xc1, 0x78, 0x92, 0xed, }, 5, 0, "", "",
120"c4 c1 78 92 ed \tkmovw %r13d,%k5",},
121{{0xc5, 0xf8, 0x93, 0xc5, }, 4, 0, "", "",
122"c5 f8 93 c5 \tkmovw %k5,%eax",},
123{{0xc5, 0xf8, 0x93, 0xed, }, 4, 0, "", "",
124"c5 f8 93 ed \tkmovw %k5,%ebp",},
125{{0xc5, 0x78, 0x93, 0xed, }, 4, 0, "", "",
126"c5 78 93 ed \tkmovw %k5,%r13d",},
127{{0xc4, 0xe1, 0xf8, 0x90, 0xee, }, 5, 0, "", "",
128"c4 e1 f8 90 ee \tkmovq %k6,%k5",},
129{{0xc4, 0xe1, 0xf8, 0x90, 0x29, }, 5, 0, "", "",
130"c4 e1 f8 90 29 \tkmovq (%rcx),%k5",},
131{{0xc4, 0xa1, 0xf8, 0x90, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
132"c4 a1 f8 90 ac f0 23 01 00 00 \tkmovq 0x123(%rax,%r14,8),%k5",},
133{{0xc4, 0xe1, 0xf8, 0x91, 0x29, }, 5, 0, "", "",
134"c4 e1 f8 91 29 \tkmovq %k5,(%rcx)",},
135{{0xc4, 0xa1, 0xf8, 0x91, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
136"c4 a1 f8 91 ac f0 23 01 00 00 \tkmovq %k5,0x123(%rax,%r14,8)",},
137{{0xc4, 0xe1, 0xfb, 0x92, 0xe8, }, 5, 0, "", "",
138"c4 e1 fb 92 e8 \tkmovq %rax,%k5",},
139{{0xc4, 0xe1, 0xfb, 0x92, 0xed, }, 5, 0, "", "",
140"c4 e1 fb 92 ed \tkmovq %rbp,%k5",},
141{{0xc4, 0xc1, 0xfb, 0x92, 0xed, }, 5, 0, "", "",
142"c4 c1 fb 92 ed \tkmovq %r13,%k5",},
143{{0xc4, 0xe1, 0xfb, 0x93, 0xc5, }, 5, 0, "", "",
144"c4 e1 fb 93 c5 \tkmovq %k5,%rax",},
145{{0xc4, 0xe1, 0xfb, 0x93, 0xed, }, 5, 0, "", "",
146"c4 e1 fb 93 ed \tkmovq %k5,%rbp",},
147{{0xc4, 0x61, 0xfb, 0x93, 0xed, }, 5, 0, "", "",
148"c4 61 fb 93 ed \tkmovq %k5,%r13",},
149{{0xc5, 0xf9, 0x90, 0xee, }, 4, 0, "", "",
150"c5 f9 90 ee \tkmovb %k6,%k5",},
151{{0xc5, 0xf9, 0x90, 0x29, }, 4, 0, "", "",
152"c5 f9 90 29 \tkmovb (%rcx),%k5",},
153{{0xc4, 0xa1, 0x79, 0x90, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
154"c4 a1 79 90 ac f0 23 01 00 00 \tkmovb 0x123(%rax,%r14,8),%k5",},
155{{0xc5, 0xf9, 0x91, 0x29, }, 4, 0, "", "",
156"c5 f9 91 29 \tkmovb %k5,(%rcx)",},
157{{0xc4, 0xa1, 0x79, 0x91, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
158"c4 a1 79 91 ac f0 23 01 00 00 \tkmovb %k5,0x123(%rax,%r14,8)",},
159{{0xc5, 0xf9, 0x92, 0xe8, }, 4, 0, "", "",
160"c5 f9 92 e8 \tkmovb %eax,%k5",},
161{{0xc5, 0xf9, 0x92, 0xed, }, 4, 0, "", "",
162"c5 f9 92 ed \tkmovb %ebp,%k5",},
163{{0xc4, 0xc1, 0x79, 0x92, 0xed, }, 5, 0, "", "",
164"c4 c1 79 92 ed \tkmovb %r13d,%k5",},
165{{0xc5, 0xf9, 0x93, 0xc5, }, 4, 0, "", "",
166"c5 f9 93 c5 \tkmovb %k5,%eax",},
167{{0xc5, 0xf9, 0x93, 0xed, }, 4, 0, "", "",
168"c5 f9 93 ed \tkmovb %k5,%ebp",},
169{{0xc5, 0x79, 0x93, 0xed, }, 4, 0, "", "",
170"c5 79 93 ed \tkmovb %k5,%r13d",},
171{{0xc4, 0xe1, 0xf9, 0x90, 0xee, }, 5, 0, "", "",
172"c4 e1 f9 90 ee \tkmovd %k6,%k5",},
173{{0xc4, 0xe1, 0xf9, 0x90, 0x29, }, 5, 0, "", "",
174"c4 e1 f9 90 29 \tkmovd (%rcx),%k5",},
175{{0xc4, 0xa1, 0xf9, 0x90, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
176"c4 a1 f9 90 ac f0 23 01 00 00 \tkmovd 0x123(%rax,%r14,8),%k5",},
177{{0xc4, 0xe1, 0xf9, 0x91, 0x29, }, 5, 0, "", "",
178"c4 e1 f9 91 29 \tkmovd %k5,(%rcx)",},
179{{0xc4, 0xa1, 0xf9, 0x91, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 10, 0, "", "",
180"c4 a1 f9 91 ac f0 23 01 00 00 \tkmovd %k5,0x123(%rax,%r14,8)",},
181{{0xc5, 0xfb, 0x92, 0xe8, }, 4, 0, "", "",
182"c5 fb 92 e8 \tkmovd %eax,%k5",},
183{{0xc5, 0xfb, 0x92, 0xed, }, 4, 0, "", "",
184"c5 fb 92 ed \tkmovd %ebp,%k5",},
185{{0xc4, 0xc1, 0x7b, 0x92, 0xed, }, 5, 0, "", "",
186"c4 c1 7b 92 ed \tkmovd %r13d,%k5",},
187{{0xc5, 0xfb, 0x93, 0xc5, }, 4, 0, "", "",
188"c5 fb 93 c5 \tkmovd %k5,%eax",},
189{{0xc5, 0xfb, 0x93, 0xed, }, 4, 0, "", "",
190"c5 fb 93 ed \tkmovd %k5,%ebp",},
191{{0xc5, 0x7b, 0x93, 0xed, }, 4, 0, "", "",
192"c5 7b 93 ed \tkmovd %k5,%r13d",},
193{{0xc5, 0xf8, 0x98, 0xee, }, 4, 0, "", "",
194"c5 f8 98 ee \tkortestw %k6,%k5",},
195{{0xc4, 0xe1, 0xf8, 0x98, 0xee, }, 5, 0, "", "",
196"c4 e1 f8 98 ee \tkortestq %k6,%k5",},
197{{0xc5, 0xf9, 0x98, 0xee, }, 4, 0, "", "",
198"c5 f9 98 ee \tkortestb %k6,%k5",},
199{{0xc4, 0xe1, 0xf9, 0x98, 0xee, }, 5, 0, "", "",
200"c4 e1 f9 98 ee \tkortestd %k6,%k5",},
201{{0xc5, 0xf8, 0x99, 0xee, }, 4, 0, "", "",
202"c5 f8 99 ee \tktestw %k6,%k5",},
203{{0xc4, 0xe1, 0xf8, 0x99, 0xee, }, 5, 0, "", "",
204"c4 e1 f8 99 ee \tktestq %k6,%k5",},
205{{0xc5, 0xf9, 0x99, 0xee, }, 4, 0, "", "",
206"c5 f9 99 ee \tktestb %k6,%k5",},
207{{0xc4, 0xe1, 0xf9, 0x99, 0xee, }, 5, 0, "", "",
208"c4 e1 f9 99 ee \tktestd %k6,%k5",},
209{{0xc4, 0xe3, 0xf9, 0x30, 0xee, 0x12, }, 6, 0, "", "",
210"c4 e3 f9 30 ee 12 \tkshiftrw $0x12,%k6,%k5",},
211{{0xc4, 0xe3, 0xf9, 0x31, 0xee, 0x5b, }, 6, 0, "", "",
212"c4 e3 f9 31 ee 5b \tkshiftrq $0x5b,%k6,%k5",},
213{{0xc4, 0xe3, 0xf9, 0x32, 0xee, 0x12, }, 6, 0, "", "",
214"c4 e3 f9 32 ee 12 \tkshiftlw $0x12,%k6,%k5",},
215{{0xc4, 0xe3, 0xf9, 0x33, 0xee, 0x5b, }, 6, 0, "", "",
216"c4 e3 f9 33 ee 5b \tkshiftlq $0x5b,%k6,%k5",},
217{{0xc5, 0xf8, 0x5b, 0xf5, }, 4, 0, "", "",
218"c5 f8 5b f5 \tvcvtdq2ps %xmm5,%xmm6",},
219{{0x62, 0x91, 0xfc, 0x4f, 0x5b, 0xf5, }, 6, 0, "", "",
220"62 91 fc 4f 5b f5 \tvcvtqq2ps %zmm29,%ymm6{%k7}",},
221{{0xc5, 0xf9, 0x5b, 0xf5, }, 4, 0, "", "",
222"c5 f9 5b f5 \tvcvtps2dq %xmm5,%xmm6",},
223{{0xc5, 0xfa, 0x5b, 0xf5, }, 4, 0, "", "",
224"c5 fa 5b f5 \tvcvttps2dq %xmm5,%xmm6",},
225{{0x0f, 0x6f, 0xe0, }, 3, 0, "", "",
226"0f 6f e0 \tmovq %mm0,%mm4",},
227{{0xc5, 0xfd, 0x6f, 0xf4, }, 4, 0, "", "",
228"c5 fd 6f f4 \tvmovdqa %ymm4,%ymm6",},
229{{0x62, 0x01, 0x7d, 0x48, 0x6f, 0xd1, }, 6, 0, "", "",
230"62 01 7d 48 6f d1 \tvmovdqa32 %zmm25,%zmm26",},
231{{0x62, 0x01, 0xfd, 0x48, 0x6f, 0xd1, }, 6, 0, "", "",
232"62 01 fd 48 6f d1 \tvmovdqa64 %zmm25,%zmm26",},
233{{0xc5, 0xfe, 0x6f, 0xf4, }, 4, 0, "", "",
234"c5 fe 6f f4 \tvmovdqu %ymm4,%ymm6",},
235{{0x62, 0x01, 0x7e, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
236"62 01 7e 48 6f f5 \tvmovdqu32 %zmm29,%zmm30",},
237{{0x62, 0x01, 0xfe, 0x48, 0x6f, 0xd1, }, 6, 0, "", "",
238"62 01 fe 48 6f d1 \tvmovdqu64 %zmm25,%zmm26",},
239{{0x62, 0x01, 0x7f, 0x48, 0x6f, 0xf5, }, 6, 0, "", "",
240"62 01 7f 48 6f f5 \tvmovdqu8 %zmm29,%zmm30",},
241{{0x62, 0x01, 0xff, 0x48, 0x6f, 0xd1, }, 6, 0, "", "",
242"62 01 ff 48 6f d1 \tvmovdqu16 %zmm25,%zmm26",},
243{{0x0f, 0x78, 0xc3, }, 3, 0, "", "",
244"0f 78 c3 \tvmread %rax,%rbx",},
245{{0x62, 0x01, 0x7c, 0x48, 0x78, 0xd1, }, 6, 0, "", "",
246"62 01 7c 48 78 d1 \tvcvttps2udq %zmm25,%zmm26",},
247{{0x62, 0x91, 0xfc, 0x4f, 0x78, 0xf5, }, 6, 0, "", "",
248"62 91 fc 4f 78 f5 \tvcvttpd2udq %zmm29,%ymm6{%k7}",},
249{{0x62, 0xf1, 0xff, 0x08, 0x78, 0xc6, }, 6, 0, "", "",
250"62 f1 ff 08 78 c6 \tvcvttsd2usi %xmm6,%rax",},
251{{0x62, 0xf1, 0xfe, 0x08, 0x78, 0xc6, }, 6, 0, "", "",
252"62 f1 fe 08 78 c6 \tvcvttss2usi %xmm6,%rax",},
253{{0x62, 0x61, 0x7d, 0x4f, 0x78, 0xd5, }, 6, 0, "", "",
254"62 61 7d 4f 78 d5 \tvcvttps2uqq %ymm5,%zmm26{%k7}",},
255{{0x62, 0x01, 0xfd, 0x48, 0x78, 0xf5, }, 6, 0, "", "",
256"62 01 fd 48 78 f5 \tvcvttpd2uqq %zmm29,%zmm30",},
257{{0x0f, 0x79, 0xd8, }, 3, 0, "", "",
258"0f 79 d8 \tvmwrite %rax,%rbx",},
259{{0x62, 0x01, 0x7c, 0x48, 0x79, 0xd1, }, 6, 0, "", "",
260"62 01 7c 48 79 d1 \tvcvtps2udq %zmm25,%zmm26",},
261{{0x62, 0x91, 0xfc, 0x4f, 0x79, 0xf5, }, 6, 0, "", "",
262"62 91 fc 4f 79 f5 \tvcvtpd2udq %zmm29,%ymm6{%k7}",},
263{{0x62, 0xf1, 0xff, 0x08, 0x79, 0xc6, }, 6, 0, "", "",
264"62 f1 ff 08 79 c6 \tvcvtsd2usi %xmm6,%rax",},
265{{0x62, 0xf1, 0xfe, 0x08, 0x79, 0xc6, }, 6, 0, "", "",
266"62 f1 fe 08 79 c6 \tvcvtss2usi %xmm6,%rax",},
267{{0x62, 0x61, 0x7d, 0x4f, 0x79, 0xd5, }, 6, 0, "", "",
268"62 61 7d 4f 79 d5 \tvcvtps2uqq %ymm5,%zmm26{%k7}",},
269{{0x62, 0x01, 0xfd, 0x48, 0x79, 0xf5, }, 6, 0, "", "",
270"62 01 fd 48 79 f5 \tvcvtpd2uqq %zmm29,%zmm30",},
271{{0x62, 0x61, 0x7e, 0x4f, 0x7a, 0xed, }, 6, 0, "", "",
272"62 61 7e 4f 7a ed \tvcvtudq2pd %ymm5,%zmm29{%k7}",},
273{{0x62, 0x01, 0xfe, 0x48, 0x7a, 0xd1, }, 6, 0, "", "",
274"62 01 fe 48 7a d1 \tvcvtuqq2pd %zmm25,%zmm26",},
275{{0x62, 0x01, 0x7f, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
276"62 01 7f 48 7a f5 \tvcvtudq2ps %zmm29,%zmm30",},
277{{0x62, 0x01, 0xff, 0x4f, 0x7a, 0xd1, }, 6, 0, "", "",
278"62 01 ff 4f 7a d1 \tvcvtuqq2ps %zmm25,%ymm26{%k7}",},
279{{0x62, 0x01, 0x7d, 0x4f, 0x7a, 0xd1, }, 6, 0, "", "",
280"62 01 7d 4f 7a d1 \tvcvttps2qq %ymm25,%zmm26{%k7}",},
281{{0x62, 0x01, 0xfd, 0x48, 0x7a, 0xf5, }, 6, 0, "", "",
282"62 01 fd 48 7a f5 \tvcvttpd2qq %zmm29,%zmm30",},
283{{0x62, 0xf1, 0x57, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
284"62 f1 57 08 7b f0 \tvcvtusi2sd %eax,%xmm5,%xmm6",},
285{{0x62, 0xf1, 0x56, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
286"62 f1 56 08 7b f0 \tvcvtusi2ss %eax,%xmm5,%xmm6",},
287{{0x62, 0x61, 0x7d, 0x4f, 0x7b, 0xd5, }, 6, 0, "", "",
288"62 61 7d 4f 7b d5 \tvcvtps2qq %ymm5,%zmm26{%k7}",},
289{{0x62, 0x01, 0xfd, 0x48, 0x7b, 0xf5, }, 6, 0, "", "",
290"62 01 fd 48 7b f5 \tvcvtpd2qq %zmm29,%zmm30",},
291{{0x0f, 0x7f, 0xc4, }, 3, 0, "", "",
292"0f 7f c4 \tmovq %mm0,%mm4",},
293{{0xc5, 0x7d, 0x7f, 0xc6, }, 4, 0, "", "",
294"c5 7d 7f c6 \tvmovdqa %ymm8,%ymm6",},
295{{0x62, 0x01, 0x7d, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
296"62 01 7d 48 7f ca \tvmovdqa32 %zmm25,%zmm26",},
297{{0x62, 0x01, 0xfd, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
298"62 01 fd 48 7f ca \tvmovdqa64 %zmm25,%zmm26",},
299{{0xc5, 0x7e, 0x7f, 0xc6, }, 4, 0, "", "",
300"c5 7e 7f c6 \tvmovdqu %ymm8,%ymm6",},
301{{0x62, 0x01, 0x7e, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
302"62 01 7e 48 7f ca \tvmovdqu32 %zmm25,%zmm26",},
303{{0x62, 0x01, 0xfe, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
304"62 01 fe 48 7f ca \tvmovdqu64 %zmm25,%zmm26",},
305{{0x62, 0x61, 0x7f, 0x48, 0x7f, 0x31, }, 6, 0, "", "",
306"62 61 7f 48 7f 31 \tvmovdqu8 %zmm30,(%rcx)",},
307{{0x62, 0x01, 0xff, 0x48, 0x7f, 0xca, }, 6, 0, "", "",
308"62 01 ff 48 7f ca \tvmovdqu16 %zmm25,%zmm26",},
309{{0x0f, 0xdb, 0xd1, }, 3, 0, "", "",
310"0f db d1 \tpand %mm1,%mm2",},
311{{0x66, 0x0f, 0xdb, 0xd1, }, 4, 0, "", "",
312"66 0f db d1 \tpand %xmm1,%xmm2",},
313{{0xc5, 0xcd, 0xdb, 0xd4, }, 4, 0, "", "",
314"c5 cd db d4 \tvpand %ymm4,%ymm6,%ymm2",},
315{{0x62, 0x01, 0x35, 0x40, 0xdb, 0xd0, }, 6, 0, "", "",
316"62 01 35 40 db d0 \tvpandd %zmm24,%zmm25,%zmm26",},
317{{0x62, 0x01, 0xb5, 0x40, 0xdb, 0xd0, }, 6, 0, "", "",
318"62 01 b5 40 db d0 \tvpandq %zmm24,%zmm25,%zmm26",},
319{{0x0f, 0xdf, 0xd1, }, 3, 0, "", "",
320"0f df d1 \tpandn %mm1,%mm2",},
321{{0x66, 0x0f, 0xdf, 0xd1, }, 4, 0, "", "",
322"66 0f df d1 \tpandn %xmm1,%xmm2",},
323{{0xc5, 0xcd, 0xdf, 0xd4, }, 4, 0, "", "",
324"c5 cd df d4 \tvpandn %ymm4,%ymm6,%ymm2",},
325{{0x62, 0x01, 0x35, 0x40, 0xdf, 0xd0, }, 6, 0, "", "",
326"62 01 35 40 df d0 \tvpandnd %zmm24,%zmm25,%zmm26",},
327{{0x62, 0x01, 0xb5, 0x40, 0xdf, 0xd0, }, 6, 0, "", "",
328"62 01 b5 40 df d0 \tvpandnq %zmm24,%zmm25,%zmm26",},
329{{0xc5, 0xf9, 0xe6, 0xd1, }, 4, 0, "", "",
330"c5 f9 e6 d1 \tvcvttpd2dq %xmm1,%xmm2",},
331{{0xc5, 0xfa, 0xe6, 0xf5, }, 4, 0, "", "",
332"c5 fa e6 f5 \tvcvtdq2pd %xmm5,%xmm6",},
333{{0x62, 0x61, 0x7e, 0x4f, 0xe6, 0xd5, }, 6, 0, "", "",
334"62 61 7e 4f e6 d5 \tvcvtdq2pd %ymm5,%zmm26{%k7}",},
335{{0x62, 0x01, 0xfe, 0x48, 0xe6, 0xd1, }, 6, 0, "", "",
336"62 01 fe 48 e6 d1 \tvcvtqq2pd %zmm25,%zmm26",},
337{{0xc5, 0xfb, 0xe6, 0xd1, }, 4, 0, "", "",
338"c5 fb e6 d1 \tvcvtpd2dq %xmm1,%xmm2",},
339{{0x0f, 0xeb, 0xf4, }, 3, 0, "", "",
340"0f eb f4 \tpor %mm4,%mm6",},
341{{0xc5, 0xcd, 0xeb, 0xd4, }, 4, 0, "", "",
342"c5 cd eb d4 \tvpor %ymm4,%ymm6,%ymm2",},
343{{0x62, 0x01, 0x35, 0x40, 0xeb, 0xd0, }, 6, 0, "", "",
344"62 01 35 40 eb d0 \tvpord %zmm24,%zmm25,%zmm26",},
345{{0x62, 0x01, 0xb5, 0x40, 0xeb, 0xd0, }, 6, 0, "", "",
346"62 01 b5 40 eb d0 \tvporq %zmm24,%zmm25,%zmm26",},
347{{0x0f, 0xef, 0xf4, }, 3, 0, "", "",
348"0f ef f4 \tpxor %mm4,%mm6",},
349{{0xc5, 0xcd, 0xef, 0xd4, }, 4, 0, "", "",
350"c5 cd ef d4 \tvpxor %ymm4,%ymm6,%ymm2",},
351{{0x62, 0x01, 0x35, 0x40, 0xef, 0xd0, }, 6, 0, "", "",
352"62 01 35 40 ef d0 \tvpxord %zmm24,%zmm25,%zmm26",},
353{{0x62, 0x01, 0xb5, 0x40, 0xef, 0xd0, }, 6, 0, "", "",
354"62 01 b5 40 ef d0 \tvpxorq %zmm24,%zmm25,%zmm26",},
355{{0x66, 0x0f, 0x38, 0x10, 0xc1, }, 5, 0, "", "",
356"66 0f 38 10 c1 \tpblendvb %xmm0,%xmm1,%xmm0",},
357{{0x62, 0x02, 0x9d, 0x40, 0x10, 0xeb, }, 6, 0, "", "",
358"62 02 9d 40 10 eb \tvpsrlvw %zmm27,%zmm28,%zmm29",},
359{{0x62, 0x62, 0x7e, 0x4f, 0x10, 0xe6, }, 6, 0, "", "",
360"62 62 7e 4f 10 e6 \tvpmovuswb %zmm28,%ymm6{%k7}",},
361{{0x62, 0x62, 0x7e, 0x4f, 0x11, 0xe6, }, 6, 0, "", "",
362"62 62 7e 4f 11 e6 \tvpmovusdb %zmm28,%xmm6{%k7}",},
363{{0x62, 0x02, 0x9d, 0x40, 0x11, 0xeb, }, 6, 0, "", "",
364"62 02 9d 40 11 eb \tvpsravw %zmm27,%zmm28,%zmm29",},
365{{0x62, 0x62, 0x7e, 0x4f, 0x12, 0xde, }, 6, 0, "", "",
366"62 62 7e 4f 12 de \tvpmovusqb %zmm27,%xmm6{%k7}",},
367{{0x62, 0x02, 0x9d, 0x40, 0x12, 0xeb, }, 6, 0, "", "",
368"62 02 9d 40 12 eb \tvpsllvw %zmm27,%zmm28,%zmm29",},
369{{0xc4, 0xe2, 0x7d, 0x13, 0xeb, }, 5, 0, "", "",
370"c4 e2 7d 13 eb \tvcvtph2ps %xmm3,%ymm5",},
371{{0x62, 0x62, 0x7d, 0x4f, 0x13, 0xdd, }, 6, 0, "", "",
372"62 62 7d 4f 13 dd \tvcvtph2ps %ymm5,%zmm27{%k7}",},
373{{0x62, 0x62, 0x7e, 0x4f, 0x13, 0xde, }, 6, 0, "", "",
374"62 62 7e 4f 13 de \tvpmovusdw %zmm27,%ymm6{%k7}",},
375{{0x66, 0x0f, 0x38, 0x14, 0xc1, }, 5, 0, "", "",
376"66 0f 38 14 c1 \tblendvps %xmm0,%xmm1,%xmm0",},
377{{0x62, 0x62, 0x7e, 0x4f, 0x14, 0xde, }, 6, 0, "", "",
378"62 62 7e 4f 14 de \tvpmovusqw %zmm27,%xmm6{%k7}",},
379{{0x62, 0x02, 0x1d, 0x40, 0x14, 0xeb, }, 6, 0, "", "",
380"62 02 1d 40 14 eb \tvprorvd %zmm27,%zmm28,%zmm29",},
381{{0x62, 0x02, 0x9d, 0x40, 0x14, 0xeb, }, 6, 0, "", "",
382"62 02 9d 40 14 eb \tvprorvq %zmm27,%zmm28,%zmm29",},
383{{0x66, 0x0f, 0x38, 0x15, 0xc1, }, 5, 0, "", "",
384"66 0f 38 15 c1 \tblendvpd %xmm0,%xmm1,%xmm0",},
385{{0x62, 0x62, 0x7e, 0x4f, 0x15, 0xde, }, 6, 0, "", "",
386"62 62 7e 4f 15 de \tvpmovusqd %zmm27,%ymm6{%k7}",},
387{{0x62, 0x02, 0x1d, 0x40, 0x15, 0xeb, }, 6, 0, "", "",
388"62 02 1d 40 15 eb \tvprolvd %zmm27,%zmm28,%zmm29",},
389{{0x62, 0x02, 0x9d, 0x40, 0x15, 0xeb, }, 6, 0, "", "",
390"62 02 9d 40 15 eb \tvprolvq %zmm27,%zmm28,%zmm29",},
391{{0xc4, 0xe2, 0x4d, 0x16, 0xd4, }, 5, 0, "", "",
392"c4 e2 4d 16 d4 \tvpermps %ymm4,%ymm6,%ymm2",},
393{{0x62, 0x82, 0x2d, 0x27, 0x16, 0xf0, }, 6, 0, "", "",
394"62 82 2d 27 16 f0 \tvpermps %ymm24,%ymm26,%ymm22{%k7}",},
395{{0x62, 0x82, 0xad, 0x27, 0x16, 0xf0, }, 6, 0, "", "",
396"62 82 ad 27 16 f0 \tvpermpd %ymm24,%ymm26,%ymm22{%k7}",},
397{{0xc4, 0xe2, 0x7d, 0x19, 0xf4, }, 5, 0, "", "",
398"c4 e2 7d 19 f4 \tvbroadcastsd %xmm4,%ymm6",},
399{{0x62, 0x02, 0x7d, 0x48, 0x19, 0xd3, }, 6, 0, "", "",
400"62 02 7d 48 19 d3 \tvbroadcastf32x2 %xmm27,%zmm26",},
401{{0xc4, 0xe2, 0x7d, 0x1a, 0x21, }, 5, 0, "", "",
402"c4 e2 7d 1a 21 \tvbroadcastf128 (%rcx),%ymm4",},
403{{0x62, 0x62, 0x7d, 0x48, 0x1a, 0x11, }, 6, 0, "", "",
404"62 62 7d 48 1a 11 \tvbroadcastf32x4 (%rcx),%zmm26",},
405{{0x62, 0x62, 0xfd, 0x48, 0x1a, 0x11, }, 6, 0, "", "",
406"62 62 fd 48 1a 11 \tvbroadcastf64x2 (%rcx),%zmm26",},
407{{0x62, 0x62, 0x7d, 0x48, 0x1b, 0x19, }, 6, 0, "", "",
408"62 62 7d 48 1b 19 \tvbroadcastf32x8 (%rcx),%zmm27",},
409{{0x62, 0x62, 0xfd, 0x48, 0x1b, 0x11, }, 6, 0, "", "",
410"62 62 fd 48 1b 11 \tvbroadcastf64x4 (%rcx),%zmm26",},
411{{0x62, 0x02, 0xfd, 0x48, 0x1f, 0xe3, }, 6, 0, "", "",
412"62 02 fd 48 1f e3 \tvpabsq %zmm27,%zmm28",},
413{{0xc4, 0xe2, 0x79, 0x20, 0xec, }, 5, 0, "", "",
414"c4 e2 79 20 ec \tvpmovsxbw %xmm4,%xmm5",},
415{{0x62, 0x62, 0x7e, 0x4f, 0x20, 0xde, }, 6, 0, "", "",
416"62 62 7e 4f 20 de \tvpmovswb %zmm27,%ymm6{%k7}",},
417{{0xc4, 0xe2, 0x7d, 0x21, 0xf4, }, 5, 0, "", "",
418"c4 e2 7d 21 f4 \tvpmovsxbd %xmm4,%ymm6",},
419{{0x62, 0x62, 0x7e, 0x4f, 0x21, 0xde, }, 6, 0, "", "",
420"62 62 7e 4f 21 de \tvpmovsdb %zmm27,%xmm6{%k7}",},
421{{0xc4, 0xe2, 0x7d, 0x22, 0xe4, }, 5, 0, "", "",
422"c4 e2 7d 22 e4 \tvpmovsxbq %xmm4,%ymm4",},
423{{0x62, 0x62, 0x7e, 0x4f, 0x22, 0xde, }, 6, 0, "", "",
424"62 62 7e 4f 22 de \tvpmovsqb %zmm27,%xmm6{%k7}",},
425{{0xc4, 0xe2, 0x7d, 0x23, 0xe4, }, 5, 0, "", "",
426"c4 e2 7d 23 e4 \tvpmovsxwd %xmm4,%ymm4",},
427{{0x62, 0x62, 0x7e, 0x4f, 0x23, 0xde, }, 6, 0, "", "",
428"62 62 7e 4f 23 de \tvpmovsdw %zmm27,%ymm6{%k7}",},
429{{0xc4, 0xe2, 0x7d, 0x24, 0xf4, }, 5, 0, "", "",
430"c4 e2 7d 24 f4 \tvpmovsxwq %xmm4,%ymm6",},
431{{0x62, 0x62, 0x7e, 0x4f, 0x24, 0xde, }, 6, 0, "", "",
432"62 62 7e 4f 24 de \tvpmovsqw %zmm27,%xmm6{%k7}",},
433{{0xc4, 0xe2, 0x7d, 0x25, 0xe4, }, 5, 0, "", "",
434"c4 e2 7d 25 e4 \tvpmovsxdq %xmm4,%ymm4",},
435{{0x62, 0x62, 0x7e, 0x4f, 0x25, 0xde, }, 6, 0, "", "",
436"62 62 7e 4f 25 de \tvpmovsqd %zmm27,%ymm6{%k7}",},
437{{0x62, 0x92, 0x1d, 0x40, 0x26, 0xeb, }, 6, 0, "", "",
438"62 92 1d 40 26 eb \tvptestmb %zmm27,%zmm28,%k5",},
439{{0x62, 0x92, 0x9d, 0x40, 0x26, 0xeb, }, 6, 0, "", "",
440"62 92 9d 40 26 eb \tvptestmw %zmm27,%zmm28,%k5",},
441{{0x62, 0x92, 0x26, 0x40, 0x26, 0xea, }, 6, 0, "", "",
442"62 92 26 40 26 ea \tvptestnmb %zmm26,%zmm27,%k5",},
443{{0x62, 0x92, 0xa6, 0x40, 0x26, 0xea, }, 6, 0, "", "",
444"62 92 a6 40 26 ea \tvptestnmw %zmm26,%zmm27,%k5",},
445{{0x62, 0x92, 0x1d, 0x40, 0x27, 0xeb, }, 6, 0, "", "",
446"62 92 1d 40 27 eb \tvptestmd %zmm27,%zmm28,%k5",},
447{{0x62, 0x92, 0x9d, 0x40, 0x27, 0xeb, }, 6, 0, "", "",
448"62 92 9d 40 27 eb \tvptestmq %zmm27,%zmm28,%k5",},
449{{0x62, 0x92, 0x26, 0x40, 0x27, 0xea, }, 6, 0, "", "",
450"62 92 26 40 27 ea \tvptestnmd %zmm26,%zmm27,%k5",},
451{{0x62, 0x92, 0xa6, 0x40, 0x27, 0xea, }, 6, 0, "", "",
452"62 92 a6 40 27 ea \tvptestnmq %zmm26,%zmm27,%k5",},
453{{0xc4, 0xe2, 0x4d, 0x28, 0xd4, }, 5, 0, "", "",
454"c4 e2 4d 28 d4 \tvpmuldq %ymm4,%ymm6,%ymm2",},
455{{0x62, 0x62, 0x7e, 0x48, 0x28, 0xe5, }, 6, 0, "", "",
456"62 62 7e 48 28 e5 \tvpmovm2b %k5,%zmm28",},
457{{0x62, 0x62, 0xfe, 0x48, 0x28, 0xe5, }, 6, 0, "", "",
458"62 62 fe 48 28 e5 \tvpmovm2w %k5,%zmm28",},
459{{0xc4, 0xe2, 0x4d, 0x29, 0xd4, }, 5, 0, "", "",
460"c4 e2 4d 29 d4 \tvpcmpeqq %ymm4,%ymm6,%ymm2",},
461{{0x62, 0x92, 0x7e, 0x48, 0x29, 0xec, }, 6, 0, "", "",
462"62 92 7e 48 29 ec \tvpmovb2m %zmm28,%k5",},
463{{0x62, 0x92, 0xfe, 0x48, 0x29, 0xec, }, 6, 0, "", "",
464"62 92 fe 48 29 ec \tvpmovw2m %zmm28,%k5",},
465{{0xc4, 0xe2, 0x7d, 0x2a, 0x21, }, 5, 0, "", "",
466"c4 e2 7d 2a 21 \tvmovntdqa (%rcx),%ymm4",},
467{{0x62, 0x62, 0xfe, 0x48, 0x2a, 0xf6, }, 6, 0, "", "",
468"62 62 fe 48 2a f6 \tvpbroadcastmb2q %k6,%zmm30",},
469{{0xc4, 0xe2, 0x5d, 0x2c, 0x31, }, 5, 0, "", "",
470"c4 e2 5d 2c 31 \tvmaskmovps (%rcx),%ymm4,%ymm6",},
471{{0x62, 0x02, 0x35, 0x40, 0x2c, 0xd0, }, 6, 0, "", "",
472"62 02 35 40 2c d0 \tvscalefps %zmm24,%zmm25,%zmm26",},
473{{0x62, 0x02, 0xb5, 0x40, 0x2c, 0xd0, }, 6, 0, "", "",
474"62 02 b5 40 2c d0 \tvscalefpd %zmm24,%zmm25,%zmm26",},
475{{0xc4, 0xe2, 0x5d, 0x2d, 0x31, }, 5, 0, "", "",
476"c4 e2 5d 2d 31 \tvmaskmovpd (%rcx),%ymm4,%ymm6",},
477{{0x62, 0x02, 0x35, 0x07, 0x2d, 0xd0, }, 6, 0, "", "",
478"62 02 35 07 2d d0 \tvscalefss %xmm24,%xmm25,%xmm26{%k7}",},
479{{0x62, 0x02, 0xb5, 0x07, 0x2d, 0xd0, }, 6, 0, "", "",
480"62 02 b5 07 2d d0 \tvscalefsd %xmm24,%xmm25,%xmm26{%k7}",},
481{{0xc4, 0xe2, 0x7d, 0x30, 0xe4, }, 5, 0, "", "",
482"c4 e2 7d 30 e4 \tvpmovzxbw %xmm4,%ymm4",},
483{{0x62, 0x62, 0x7e, 0x4f, 0x30, 0xde, }, 6, 0, "", "",
484"62 62 7e 4f 30 de \tvpmovwb %zmm27,%ymm6{%k7}",},
485{{0xc4, 0xe2, 0x7d, 0x31, 0xf4, }, 5, 0, "", "",
486"c4 e2 7d 31 f4 \tvpmovzxbd %xmm4,%ymm6",},
487{{0x62, 0x62, 0x7e, 0x4f, 0x31, 0xde, }, 6, 0, "", "",
488"62 62 7e 4f 31 de \tvpmovdb %zmm27,%xmm6{%k7}",},
489{{0xc4, 0xe2, 0x7d, 0x32, 0xe4, }, 5, 0, "", "",
490"c4 e2 7d 32 e4 \tvpmovzxbq %xmm4,%ymm4",},
491{{0x62, 0x62, 0x7e, 0x4f, 0x32, 0xde, }, 6, 0, "", "",
492"62 62 7e 4f 32 de \tvpmovqb %zmm27,%xmm6{%k7}",},
493{{0xc4, 0xe2, 0x7d, 0x33, 0xe4, }, 5, 0, "", "",
494"c4 e2 7d 33 e4 \tvpmovzxwd %xmm4,%ymm4",},
495{{0x62, 0x62, 0x7e, 0x4f, 0x33, 0xde, }, 6, 0, "", "",
496"62 62 7e 4f 33 de \tvpmovdw %zmm27,%ymm6{%k7}",},
497{{0xc4, 0xe2, 0x7d, 0x34, 0xf4, }, 5, 0, "", "",
498"c4 e2 7d 34 f4 \tvpmovzxwq %xmm4,%ymm6",},
499{{0x62, 0x62, 0x7e, 0x4f, 0x34, 0xde, }, 6, 0, "", "",
500"62 62 7e 4f 34 de \tvpmovqw %zmm27,%xmm6{%k7}",},
501{{0xc4, 0xe2, 0x7d, 0x35, 0xe4, }, 5, 0, "", "",
502"c4 e2 7d 35 e4 \tvpmovzxdq %xmm4,%ymm4",},
503{{0x62, 0x62, 0x7e, 0x4f, 0x35, 0xde, }, 6, 0, "", "",
504"62 62 7e 4f 35 de \tvpmovqd %zmm27,%ymm6{%k7}",},
505{{0xc4, 0xe2, 0x4d, 0x36, 0xd4, }, 5, 0, "", "",
506"c4 e2 4d 36 d4 \tvpermd %ymm4,%ymm6,%ymm2",},
507{{0x62, 0x82, 0x2d, 0x27, 0x36, 0xf0, }, 6, 0, "", "",
508"62 82 2d 27 36 f0 \tvpermd %ymm24,%ymm26,%ymm22{%k7}",},
509{{0x62, 0x82, 0xad, 0x27, 0x36, 0xf0, }, 6, 0, "", "",
510"62 82 ad 27 36 f0 \tvpermq %ymm24,%ymm26,%ymm22{%k7}",},
511{{0xc4, 0xe2, 0x4d, 0x38, 0xd4, }, 5, 0, "", "",
512"c4 e2 4d 38 d4 \tvpminsb %ymm4,%ymm6,%ymm2",},
513{{0x62, 0x62, 0x7e, 0x48, 0x38, 0xe5, }, 6, 0, "", "",
514"62 62 7e 48 38 e5 \tvpmovm2d %k5,%zmm28",},
515{{0x62, 0x62, 0xfe, 0x48, 0x38, 0xe5, }, 6, 0, "", "",
516"62 62 fe 48 38 e5 \tvpmovm2q %k5,%zmm28",},
517{{0xc4, 0xe2, 0x69, 0x39, 0xd9, }, 5, 0, "", "",
518"c4 e2 69 39 d9 \tvpminsd %xmm1,%xmm2,%xmm3",},
519{{0x62, 0x02, 0x35, 0x40, 0x39, 0xd0, }, 6, 0, "", "",
520"62 02 35 40 39 d0 \tvpminsd %zmm24,%zmm25,%zmm26",},
521{{0x62, 0x02, 0xb5, 0x40, 0x39, 0xd0, }, 6, 0, "", "",
522"62 02 b5 40 39 d0 \tvpminsq %zmm24,%zmm25,%zmm26",},
523{{0x62, 0x92, 0x7e, 0x48, 0x39, 0xec, }, 6, 0, "", "",
524"62 92 7e 48 39 ec \tvpmovd2m %zmm28,%k5",},
525{{0x62, 0x92, 0xfe, 0x48, 0x39, 0xec, }, 6, 0, "", "",
526"62 92 fe 48 39 ec \tvpmovq2m %zmm28,%k5",},
527{{0xc4, 0xe2, 0x4d, 0x3a, 0xd4, }, 5, 0, "", "",
528"c4 e2 4d 3a d4 \tvpminuw %ymm4,%ymm6,%ymm2",},
529{{0x62, 0x62, 0x7e, 0x48, 0x3a, 0xe6, }, 6, 0, "", "",
530"62 62 7e 48 3a e6 \tvpbroadcastmw2d %k6,%zmm28",},
531{{0xc4, 0xe2, 0x4d, 0x3b, 0xd4, }, 5, 0, "", "",
532"c4 e2 4d 3b d4 \tvpminud %ymm4,%ymm6,%ymm2",},
533{{0x62, 0x02, 0x35, 0x40, 0x3b, 0xd0, }, 6, 0, "", "",
534"62 02 35 40 3b d0 \tvpminud %zmm24,%zmm25,%zmm26",},
535{{0x62, 0x02, 0xb5, 0x40, 0x3b, 0xd0, }, 6, 0, "", "",
536"62 02 b5 40 3b d0 \tvpminuq %zmm24,%zmm25,%zmm26",},
537{{0xc4, 0xe2, 0x4d, 0x3d, 0xd4, }, 5, 0, "", "",
538"c4 e2 4d 3d d4 \tvpmaxsd %ymm4,%ymm6,%ymm2",},
539{{0x62, 0x02, 0x35, 0x40, 0x3d, 0xd0, }, 6, 0, "", "",
540"62 02 35 40 3d d0 \tvpmaxsd %zmm24,%zmm25,%zmm26",},
541{{0x62, 0x02, 0xb5, 0x40, 0x3d, 0xd0, }, 6, 0, "", "",
542"62 02 b5 40 3d d0 \tvpmaxsq %zmm24,%zmm25,%zmm26",},
543{{0xc4, 0xe2, 0x4d, 0x3f, 0xd4, }, 5, 0, "", "",
544"c4 e2 4d 3f d4 \tvpmaxud %ymm4,%ymm6,%ymm2",},
545{{0x62, 0x02, 0x35, 0x40, 0x3f, 0xd0, }, 6, 0, "", "",
546"62 02 35 40 3f d0 \tvpmaxud %zmm24,%zmm25,%zmm26",},
547{{0x62, 0x02, 0xb5, 0x40, 0x3f, 0xd0, }, 6, 0, "", "",
548"62 02 b5 40 3f d0 \tvpmaxuq %zmm24,%zmm25,%zmm26",},
549{{0xc4, 0xe2, 0x4d, 0x40, 0xd4, }, 5, 0, "", "",
550"c4 e2 4d 40 d4 \tvpmulld %ymm4,%ymm6,%ymm2",},
551{{0x62, 0x02, 0x35, 0x40, 0x40, 0xd0, }, 6, 0, "", "",
552"62 02 35 40 40 d0 \tvpmulld %zmm24,%zmm25,%zmm26",},
553{{0x62, 0x02, 0xb5, 0x40, 0x40, 0xd0, }, 6, 0, "", "",
554"62 02 b5 40 40 d0 \tvpmullq %zmm24,%zmm25,%zmm26",},
555{{0x62, 0x02, 0x7d, 0x48, 0x42, 0xd1, }, 6, 0, "", "",
556"62 02 7d 48 42 d1 \tvgetexpps %zmm25,%zmm26",},
557{{0x62, 0x02, 0xfd, 0x48, 0x42, 0xe3, }, 6, 0, "", "",
558"62 02 fd 48 42 e3 \tvgetexppd %zmm27,%zmm28",},
559{{0x62, 0x02, 0x35, 0x07, 0x43, 0xd0, }, 6, 0, "", "",
560"62 02 35 07 43 d0 \tvgetexpss %xmm24,%xmm25,%xmm26{%k7}",},
561{{0x62, 0x02, 0x95, 0x07, 0x43, 0xf4, }, 6, 0, "", "",
562"62 02 95 07 43 f4 \tvgetexpsd %xmm28,%xmm29,%xmm30{%k7}",},
563{{0x62, 0x02, 0x7d, 0x48, 0x44, 0xe3, }, 6, 0, "", "",
564"62 02 7d 48 44 e3 \tvplzcntd %zmm27,%zmm28",},
565{{0x62, 0x02, 0xfd, 0x48, 0x44, 0xe3, }, 6, 0, "", "",
566"62 02 fd 48 44 e3 \tvplzcntq %zmm27,%zmm28",},
567{{0xc4, 0xe2, 0x4d, 0x46, 0xd4, }, 5, 0, "", "",
568"c4 e2 4d 46 d4 \tvpsravd %ymm4,%ymm6,%ymm2",},
569{{0x62, 0x02, 0x35, 0x40, 0x46, 0xd0, }, 6, 0, "", "",
570"62 02 35 40 46 d0 \tvpsravd %zmm24,%zmm25,%zmm26",},
571{{0x62, 0x02, 0xb5, 0x40, 0x46, 0xd0, }, 6, 0, "", "",
572"62 02 b5 40 46 d0 \tvpsravq %zmm24,%zmm25,%zmm26",},
573{{0x62, 0x02, 0x7d, 0x48, 0x4c, 0xd1, }, 6, 0, "", "",
574"62 02 7d 48 4c d1 \tvrcp14ps %zmm25,%zmm26",},
575{{0x62, 0x02, 0xfd, 0x48, 0x4c, 0xe3, }, 6, 0, "", "",
576"62 02 fd 48 4c e3 \tvrcp14pd %zmm27,%zmm28",},
577{{0x62, 0x02, 0x35, 0x07, 0x4d, 0xd0, }, 6, 0, "", "",
578"62 02 35 07 4d d0 \tvrcp14ss %xmm24,%xmm25,%xmm26{%k7}",},
579{{0x62, 0x02, 0xb5, 0x07, 0x4d, 0xd0, }, 6, 0, "", "",
580"62 02 b5 07 4d d0 \tvrcp14sd %xmm24,%xmm25,%xmm26{%k7}",},
581{{0x62, 0x02, 0x7d, 0x48, 0x4e, 0xd1, }, 6, 0, "", "",
582"62 02 7d 48 4e d1 \tvrsqrt14ps %zmm25,%zmm26",},
583{{0x62, 0x02, 0xfd, 0x48, 0x4e, 0xe3, }, 6, 0, "", "",
584"62 02 fd 48 4e e3 \tvrsqrt14pd %zmm27,%zmm28",},
585{{0x62, 0x02, 0x35, 0x07, 0x4f, 0xd0, }, 6, 0, "", "",
586"62 02 35 07 4f d0 \tvrsqrt14ss %xmm24,%xmm25,%xmm26{%k7}",},
587{{0x62, 0x02, 0xb5, 0x07, 0x4f, 0xd0, }, 6, 0, "", "",
588"62 02 b5 07 4f d0 \tvrsqrt14sd %xmm24,%xmm25,%xmm26{%k7}",},
589{{0xc4, 0xe2, 0x79, 0x59, 0xf4, }, 5, 0, "", "",
590"c4 e2 79 59 f4 \tvpbroadcastq %xmm4,%xmm6",},
591{{0x62, 0x02, 0x7d, 0x48, 0x59, 0xd3, }, 6, 0, "", "",
592"62 02 7d 48 59 d3 \tvbroadcasti32x2 %xmm27,%zmm26",},
593{{0xc4, 0xe2, 0x7d, 0x5a, 0x21, }, 5, 0, "", "",
594"c4 e2 7d 5a 21 \tvbroadcasti128 (%rcx),%ymm4",},
595{{0x62, 0x62, 0x7d, 0x48, 0x5a, 0x11, }, 6, 0, "", "",
596"62 62 7d 48 5a 11 \tvbroadcasti32x4 (%rcx),%zmm26",},
597{{0x62, 0x62, 0xfd, 0x48, 0x5a, 0x11, }, 6, 0, "", "",
598"62 62 fd 48 5a 11 \tvbroadcasti64x2 (%rcx),%zmm26",},
599{{0x62, 0x62, 0x7d, 0x48, 0x5b, 0x21, }, 6, 0, "", "",
600"62 62 7d 48 5b 21 \tvbroadcasti32x8 (%rcx),%zmm28",},
601{{0x62, 0x62, 0xfd, 0x48, 0x5b, 0x11, }, 6, 0, "", "",
602"62 62 fd 48 5b 11 \tvbroadcasti64x4 (%rcx),%zmm26",},
603{{0x62, 0x02, 0x25, 0x40, 0x64, 0xe2, }, 6, 0, "", "",
604"62 02 25 40 64 e2 \tvpblendmd %zmm26,%zmm27,%zmm28",},
605{{0x62, 0x02, 0xa5, 0x40, 0x64, 0xe2, }, 6, 0, "", "",
606"62 02 a5 40 64 e2 \tvpblendmq %zmm26,%zmm27,%zmm28",},
607{{0x62, 0x02, 0x35, 0x40, 0x65, 0xd0, }, 6, 0, "", "",
608"62 02 35 40 65 d0 \tvblendmps %zmm24,%zmm25,%zmm26",},
609{{0x62, 0x02, 0xa5, 0x40, 0x65, 0xe2, }, 6, 0, "", "",
610"62 02 a5 40 65 e2 \tvblendmpd %zmm26,%zmm27,%zmm28",},
611{{0x62, 0x02, 0x25, 0x40, 0x66, 0xe2, }, 6, 0, "", "",
612"62 02 25 40 66 e2 \tvpblendmb %zmm26,%zmm27,%zmm28",},
613{{0x62, 0x02, 0xa5, 0x40, 0x66, 0xe2, }, 6, 0, "", "",
614"62 02 a5 40 66 e2 \tvpblendmw %zmm26,%zmm27,%zmm28",},
615{{0x62, 0x02, 0x35, 0x40, 0x75, 0xd0, }, 6, 0, "", "",
616"62 02 35 40 75 d0 \tvpermi2b %zmm24,%zmm25,%zmm26",},
617{{0x62, 0x02, 0xa5, 0x40, 0x75, 0xe2, }, 6, 0, "", "",
618"62 02 a5 40 75 e2 \tvpermi2w %zmm26,%zmm27,%zmm28",},
619{{0x62, 0x02, 0x25, 0x40, 0x76, 0xe2, }, 6, 0, "", "",
620"62 02 25 40 76 e2 \tvpermi2d %zmm26,%zmm27,%zmm28",},
621{{0x62, 0x02, 0xa5, 0x40, 0x76, 0xe2, }, 6, 0, "", "",
622"62 02 a5 40 76 e2 \tvpermi2q %zmm26,%zmm27,%zmm28",},
623{{0x62, 0x02, 0x25, 0x40, 0x77, 0xe2, }, 6, 0, "", "",
624"62 02 25 40 77 e2 \tvpermi2ps %zmm26,%zmm27,%zmm28",},
625{{0x62, 0x02, 0xa5, 0x40, 0x77, 0xe2, }, 6, 0, "", "",
626"62 02 a5 40 77 e2 \tvpermi2pd %zmm26,%zmm27,%zmm28",},
627{{0x62, 0x62, 0x7d, 0x08, 0x7a, 0xf0, }, 6, 0, "", "",
628"62 62 7d 08 7a f0 \tvpbroadcastb %eax,%xmm30",},
629{{0x62, 0x62, 0x7d, 0x08, 0x7b, 0xf0, }, 6, 0, "", "",
630"62 62 7d 08 7b f0 \tvpbroadcastw %eax,%xmm30",},
631{{0x62, 0x62, 0x7d, 0x08, 0x7c, 0xf0, }, 6, 0, "", "",
632"62 62 7d 08 7c f0 \tvpbroadcastd %eax,%xmm30",},
633{{0x62, 0x62, 0xfd, 0x48, 0x7c, 0xf0, }, 6, 0, "", "",
634"62 62 fd 48 7c f0 \tvpbroadcastq %rax,%zmm30",},
635{{0x62, 0x02, 0x25, 0x40, 0x7d, 0xe2, }, 6, 0, "", "",
636"62 02 25 40 7d e2 \tvpermt2b %zmm26,%zmm27,%zmm28",},
637{{0x62, 0x02, 0xa5, 0x40, 0x7d, 0xe2, }, 6, 0, "", "",
638"62 02 a5 40 7d e2 \tvpermt2w %zmm26,%zmm27,%zmm28",},
639{{0x62, 0x02, 0x25, 0x40, 0x7e, 0xe2, }, 6, 0, "", "",
640"62 02 25 40 7e e2 \tvpermt2d %zmm26,%zmm27,%zmm28",},
641{{0x62, 0x02, 0xa5, 0x40, 0x7e, 0xe2, }, 6, 0, "", "",
642"62 02 a5 40 7e e2 \tvpermt2q %zmm26,%zmm27,%zmm28",},
643{{0x62, 0x02, 0x25, 0x40, 0x7f, 0xe2, }, 6, 0, "", "",
644"62 02 25 40 7f e2 \tvpermt2ps %zmm26,%zmm27,%zmm28",},
645{{0x62, 0x02, 0xa5, 0x40, 0x7f, 0xe2, }, 6, 0, "", "",
646"62 02 a5 40 7f e2 \tvpermt2pd %zmm26,%zmm27,%zmm28",},
647{{0x62, 0x02, 0xa5, 0x40, 0x83, 0xe2, }, 6, 0, "", "",
648"62 02 a5 40 83 e2 \tvpmultishiftqb %zmm26,%zmm27,%zmm28",},
649{{0x62, 0x62, 0x7d, 0x48, 0x88, 0x11, }, 6, 0, "", "",
650"62 62 7d 48 88 11 \tvexpandps (%rcx),%zmm26",},
651{{0x62, 0x62, 0xfd, 0x48, 0x88, 0x21, }, 6, 0, "", "",
652"62 62 fd 48 88 21 \tvexpandpd (%rcx),%zmm28",},
653{{0x62, 0x62, 0x7d, 0x48, 0x89, 0x21, }, 6, 0, "", "",
654"62 62 7d 48 89 21 \tvpexpandd (%rcx),%zmm28",},
655{{0x62, 0x62, 0xfd, 0x48, 0x89, 0x11, }, 6, 0, "", "",
656"62 62 fd 48 89 11 \tvpexpandq (%rcx),%zmm26",},
657{{0x62, 0x62, 0x7d, 0x48, 0x8a, 0x21, }, 6, 0, "", "",
658"62 62 7d 48 8a 21 \tvcompressps %zmm28,(%rcx)",},
659{{0x62, 0x62, 0xfd, 0x48, 0x8a, 0x21, }, 6, 0, "", "",
660"62 62 fd 48 8a 21 \tvcompresspd %zmm28,(%rcx)",},
661{{0x62, 0x62, 0x7d, 0x48, 0x8b, 0x21, }, 6, 0, "", "",
662"62 62 7d 48 8b 21 \tvpcompressd %zmm28,(%rcx)",},
663{{0x62, 0x62, 0xfd, 0x48, 0x8b, 0x11, }, 6, 0, "", "",
664"62 62 fd 48 8b 11 \tvpcompressq %zmm26,(%rcx)",},
665{{0x62, 0x02, 0x25, 0x40, 0x8d, 0xe2, }, 6, 0, "", "",
666"62 02 25 40 8d e2 \tvpermb %zmm26,%zmm27,%zmm28",},
667{{0x62, 0x02, 0xa5, 0x40, 0x8d, 0xe2, }, 6, 0, "", "",
668"62 02 a5 40 8d e2 \tvpermw %zmm26,%zmm27,%zmm28",},
669{{0xc4, 0xe2, 0x69, 0x90, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
670"c4 e2 69 90 4c 7d 02 \tvpgatherdd %xmm2,0x2(%rbp,%xmm7,2),%xmm1",},
671{{0xc4, 0xe2, 0xe9, 0x90, 0x4c, 0x7d, 0x04, }, 7, 0, "", "",
672"c4 e2 e9 90 4c 7d 04 \tvpgatherdq %xmm2,0x4(%rbp,%xmm7,2),%xmm1",},
673{{0x62, 0x22, 0x7d, 0x41, 0x90, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
674"62 22 7d 41 90 94 dd 7b 00 00 00 \tvpgatherdd 0x7b(%rbp,%zmm27,8),%zmm26{%k1}",},
675{{0x62, 0x22, 0xfd, 0x41, 0x90, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
676"62 22 fd 41 90 94 dd 7b 00 00 00 \tvpgatherdq 0x7b(%rbp,%ymm27,8),%zmm26{%k1}",},
677{{0xc4, 0xe2, 0x69, 0x91, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
678"c4 e2 69 91 4c 7d 02 \tvpgatherqd %xmm2,0x2(%rbp,%xmm7,2),%xmm1",},
679{{0xc4, 0xe2, 0xe9, 0x91, 0x4c, 0x7d, 0x02, }, 7, 0, "", "",
680"c4 e2 e9 91 4c 7d 02 \tvpgatherqq %xmm2,0x2(%rbp,%xmm7,2),%xmm1",},
681{{0x62, 0x22, 0x7d, 0x41, 0x91, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
682"62 22 7d 41 91 94 dd 7b 00 00 00 \tvpgatherqd 0x7b(%rbp,%zmm27,8),%ymm26{%k1}",},
683{{0x62, 0x22, 0xfd, 0x41, 0x91, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
684"62 22 fd 41 91 94 dd 7b 00 00 00 \tvpgatherqq 0x7b(%rbp,%zmm27,8),%zmm26{%k1}",},
685{{0x62, 0x22, 0x7d, 0x41, 0xa0, 0xa4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
686"62 22 7d 41 a0 a4 ed 7b 00 00 00 \tvpscatterdd %zmm28,0x7b(%rbp,%zmm29,8){%k1}",},
687{{0x62, 0x22, 0xfd, 0x41, 0xa0, 0x94, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
688"62 22 fd 41 a0 94 dd 7b 00 00 00 \tvpscatterdq %zmm26,0x7b(%rbp,%ymm27,8){%k1}",},
689{{0x62, 0xb2, 0x7d, 0x41, 0xa1, 0xb4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
690"62 b2 7d 41 a1 b4 ed 7b 00 00 00 \tvpscatterqd %ymm6,0x7b(%rbp,%zmm29,8){%k1}",},
691{{0x62, 0xb2, 0xfd, 0x21, 0xa1, 0xb4, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
692"62 b2 fd 21 a1 b4 dd 7b 00 00 00 \tvpscatterqq %ymm6,0x7b(%rbp,%ymm27,8){%k1}",},
693{{0x62, 0x22, 0x7d, 0x41, 0xa2, 0xa4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
694"62 22 7d 41 a2 a4 ed 7b 00 00 00 \tvscatterdps %zmm28,0x7b(%rbp,%zmm29,8){%k1}",},
695{{0x62, 0x22, 0xfd, 0x41, 0xa2, 0xa4, 0xdd, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
696"62 22 fd 41 a2 a4 dd 7b 00 00 00 \tvscatterdpd %zmm28,0x7b(%rbp,%ymm27,8){%k1}",},
697{{0x62, 0xb2, 0x7d, 0x41, 0xa3, 0xb4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
698"62 b2 7d 41 a3 b4 ed 7b 00 00 00 \tvscatterqps %ymm6,0x7b(%rbp,%zmm29,8){%k1}",},
699{{0x62, 0x22, 0xfd, 0x41, 0xa3, 0xa4, 0xed, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
700"62 22 fd 41 a3 a4 ed 7b 00 00 00 \tvscatterqpd %zmm28,0x7b(%rbp,%zmm29,8){%k1}",},
701{{0x62, 0x02, 0xa5, 0x40, 0xb4, 0xe2, }, 6, 0, "", "",
702"62 02 a5 40 b4 e2 \tvpmadd52luq %zmm26,%zmm27,%zmm28",},
703{{0x62, 0x02, 0xa5, 0x40, 0xb5, 0xe2, }, 6, 0, "", "",
704"62 02 a5 40 b5 e2 \tvpmadd52huq %zmm26,%zmm27,%zmm28",},
705{{0x62, 0x02, 0x7d, 0x48, 0xc4, 0xda, }, 6, 0, "", "",
706"62 02 7d 48 c4 da \tvpconflictd %zmm26,%zmm27",},
707{{0x62, 0x02, 0xfd, 0x48, 0xc4, 0xda, }, 6, 0, "", "",
708"62 02 fd 48 c4 da \tvpconflictq %zmm26,%zmm27",},
709{{0x62, 0x02, 0x7d, 0x48, 0xc8, 0xf5, }, 6, 0, "", "",
710"62 02 7d 48 c8 f5 \tvexp2ps %zmm29,%zmm30",},
711{{0x62, 0x02, 0xfd, 0x48, 0xc8, 0xda, }, 6, 0, "", "",
712"62 02 fd 48 c8 da \tvexp2pd %zmm26,%zmm27",},
713{{0x62, 0x02, 0x7d, 0x48, 0xca, 0xf5, }, 6, 0, "", "",
714"62 02 7d 48 ca f5 \tvrcp28ps %zmm29,%zmm30",},
715{{0x62, 0x02, 0xfd, 0x48, 0xca, 0xda, }, 6, 0, "", "",
716"62 02 fd 48 ca da \tvrcp28pd %zmm26,%zmm27",},
717{{0x62, 0x02, 0x15, 0x07, 0xcb, 0xf4, }, 6, 0, "", "",
718"62 02 15 07 cb f4 \tvrcp28ss %xmm28,%xmm29,%xmm30{%k7}",},
719{{0x62, 0x02, 0xad, 0x07, 0xcb, 0xd9, }, 6, 0, "", "",
720"62 02 ad 07 cb d9 \tvrcp28sd %xmm25,%xmm26,%xmm27{%k7}",},
721{{0x62, 0x02, 0x7d, 0x48, 0xcc, 0xf5, }, 6, 0, "", "",
722"62 02 7d 48 cc f5 \tvrsqrt28ps %zmm29,%zmm30",},
723{{0x62, 0x02, 0xfd, 0x48, 0xcc, 0xda, }, 6, 0, "", "",
724"62 02 fd 48 cc da \tvrsqrt28pd %zmm26,%zmm27",},
725{{0x62, 0x02, 0x15, 0x07, 0xcd, 0xf4, }, 6, 0, "", "",
726"62 02 15 07 cd f4 \tvrsqrt28ss %xmm28,%xmm29,%xmm30{%k7}",},
727{{0x62, 0x02, 0xad, 0x07, 0xcd, 0xd9, }, 6, 0, "", "",
728"62 02 ad 07 cd d9 \tvrsqrt28sd %xmm25,%xmm26,%xmm27{%k7}",},
729{{0x62, 0x03, 0x15, 0x40, 0x03, 0xf4, 0x12, }, 7, 0, "", "",
730"62 03 15 40 03 f4 12 \tvalignd $0x12,%zmm28,%zmm29,%zmm30",},
731{{0x62, 0x03, 0xad, 0x40, 0x03, 0xd9, 0x12, }, 7, 0, "", "",
732"62 03 ad 40 03 d9 12 \tvalignq $0x12,%zmm25,%zmm26,%zmm27",},
733{{0xc4, 0xe3, 0x7d, 0x08, 0xd6, 0x05, }, 6, 0, "", "",
734"c4 e3 7d 08 d6 05 \tvroundps $0x5,%ymm6,%ymm2",},
735{{0x62, 0x03, 0x7d, 0x48, 0x08, 0xd1, 0x12, }, 7, 0, "", "",
736"62 03 7d 48 08 d1 12 \tvrndscaleps $0x12,%zmm25,%zmm26",},
737{{0xc4, 0xe3, 0x7d, 0x09, 0xd6, 0x05, }, 6, 0, "", "",
738"c4 e3 7d 09 d6 05 \tvroundpd $0x5,%ymm6,%ymm2",},
739{{0x62, 0x03, 0xfd, 0x48, 0x09, 0xd1, 0x12, }, 7, 0, "", "",
740"62 03 fd 48 09 d1 12 \tvrndscalepd $0x12,%zmm25,%zmm26",},
741{{0xc4, 0xe3, 0x49, 0x0a, 0xd4, 0x05, }, 6, 0, "", "",
742"c4 e3 49 0a d4 05 \tvroundss $0x5,%xmm4,%xmm6,%xmm2",},
743{{0x62, 0x03, 0x35, 0x07, 0x0a, 0xd0, 0x12, }, 7, 0, "", "",
744"62 03 35 07 0a d0 12 \tvrndscaless $0x12,%xmm24,%xmm25,%xmm26{%k7}",},
745{{0xc4, 0xe3, 0x49, 0x0b, 0xd4, 0x05, }, 6, 0, "", "",
746"c4 e3 49 0b d4 05 \tvroundsd $0x5,%xmm4,%xmm6,%xmm2",},
747{{0x62, 0x03, 0xb5, 0x07, 0x0b, 0xd0, 0x12, }, 7, 0, "", "",
748"62 03 b5 07 0b d0 12 \tvrndscalesd $0x12,%xmm24,%xmm25,%xmm26{%k7}",},
749{{0xc4, 0xe3, 0x5d, 0x18, 0xf4, 0x05, }, 6, 0, "", "",
750"c4 e3 5d 18 f4 05 \tvinsertf128 $0x5,%xmm4,%ymm4,%ymm6",},
751{{0x62, 0x03, 0x35, 0x47, 0x18, 0xd0, 0x12, }, 7, 0, "", "",
752"62 03 35 47 18 d0 12 \tvinsertf32x4 $0x12,%xmm24,%zmm25,%zmm26{%k7}",},
753{{0x62, 0x03, 0xb5, 0x47, 0x18, 0xd0, 0x12, }, 7, 0, "", "",
754"62 03 b5 47 18 d0 12 \tvinsertf64x2 $0x12,%xmm24,%zmm25,%zmm26{%k7}",},
755{{0xc4, 0xe3, 0x7d, 0x19, 0xe4, 0x05, }, 6, 0, "", "",
756"c4 e3 7d 19 e4 05 \tvextractf128 $0x5,%ymm4,%xmm4",},
757{{0x62, 0x03, 0x7d, 0x4f, 0x19, 0xca, 0x12, }, 7, 0, "", "",
758"62 03 7d 4f 19 ca 12 \tvextractf32x4 $0x12,%zmm25,%xmm26{%k7}",},
759{{0x62, 0x03, 0xfd, 0x4f, 0x19, 0xca, 0x12, }, 7, 0, "", "",
760"62 03 fd 4f 19 ca 12 \tvextractf64x2 $0x12,%zmm25,%xmm26{%k7}",},
761{{0x62, 0x03, 0x2d, 0x47, 0x1a, 0xd9, 0x12, }, 7, 0, "", "",
762"62 03 2d 47 1a d9 12 \tvinsertf32x8 $0x12,%ymm25,%zmm26,%zmm27{%k7}",},
763{{0x62, 0x03, 0x95, 0x47, 0x1a, 0xf4, 0x12, }, 7, 0, "", "",
764"62 03 95 47 1a f4 12 \tvinsertf64x4 $0x12,%ymm28,%zmm29,%zmm30{%k7}",},
765{{0x62, 0x03, 0x7d, 0x4f, 0x1b, 0xee, 0x12, }, 7, 0, "", "",
766"62 03 7d 4f 1b ee 12 \tvextractf32x8 $0x12,%zmm29,%ymm30{%k7}",},
767{{0x62, 0x03, 0xfd, 0x4f, 0x1b, 0xd3, 0x12, }, 7, 0, "", "",
768"62 03 fd 4f 1b d3 12 \tvextractf64x4 $0x12,%zmm26,%ymm27{%k7}",},
769{{0x62, 0x93, 0x0d, 0x40, 0x1e, 0xed, 0x12, }, 7, 0, "", "",
770"62 93 0d 40 1e ed 12 \tvpcmpud $0x12,%zmm29,%zmm30,%k5",},
771{{0x62, 0x93, 0xa5, 0x40, 0x1e, 0xea, 0x12, }, 7, 0, "", "",
772"62 93 a5 40 1e ea 12 \tvpcmpuq $0x12,%zmm26,%zmm27,%k5",},
773{{0x62, 0x93, 0x0d, 0x40, 0x1f, 0xed, 0x12, }, 7, 0, "", "",
774"62 93 0d 40 1f ed 12 \tvpcmpd $0x12,%zmm29,%zmm30,%k5",},
775{{0x62, 0x93, 0xa5, 0x40, 0x1f, 0xea, 0x12, }, 7, 0, "", "",
776"62 93 a5 40 1f ea 12 \tvpcmpq $0x12,%zmm26,%zmm27,%k5",},
777{{0x62, 0x03, 0x15, 0x40, 0x23, 0xf4, 0x12, }, 7, 0, "", "",
778"62 03 15 40 23 f4 12 \tvshuff32x4 $0x12,%zmm28,%zmm29,%zmm30",},
779{{0x62, 0x03, 0xad, 0x40, 0x23, 0xd9, 0x12, }, 7, 0, "", "",
780"62 03 ad 40 23 d9 12 \tvshuff64x2 $0x12,%zmm25,%zmm26,%zmm27",},
781{{0x62, 0x03, 0x15, 0x40, 0x25, 0xf4, 0x12, }, 7, 0, "", "",
782"62 03 15 40 25 f4 12 \tvpternlogd $0x12,%zmm28,%zmm29,%zmm30",},
783{{0x62, 0x03, 0x95, 0x40, 0x25, 0xf4, 0x12, }, 7, 0, "", "",
784"62 03 95 40 25 f4 12 \tvpternlogq $0x12,%zmm28,%zmm29,%zmm30",},
785{{0x62, 0x03, 0x7d, 0x48, 0x26, 0xda, 0x12, }, 7, 0, "", "",
786"62 03 7d 48 26 da 12 \tvgetmantps $0x12,%zmm26,%zmm27",},
787{{0x62, 0x03, 0xfd, 0x48, 0x26, 0xf5, 0x12, }, 7, 0, "", "",
788"62 03 fd 48 26 f5 12 \tvgetmantpd $0x12,%zmm29,%zmm30",},
789{{0x62, 0x03, 0x2d, 0x07, 0x27, 0xd9, 0x12, }, 7, 0, "", "",
790"62 03 2d 07 27 d9 12 \tvgetmantss $0x12,%xmm25,%xmm26,%xmm27{%k7}",},
791{{0x62, 0x03, 0x95, 0x07, 0x27, 0xf4, 0x12, }, 7, 0, "", "",
792"62 03 95 07 27 f4 12 \tvgetmantsd $0x12,%xmm28,%xmm29,%xmm30{%k7}",},
793{{0xc4, 0xe3, 0x5d, 0x38, 0xf4, 0x05, }, 6, 0, "", "",
794"c4 e3 5d 38 f4 05 \tvinserti128 $0x5,%xmm4,%ymm4,%ymm6",},
795{{0x62, 0x03, 0x35, 0x47, 0x38, 0xd0, 0x12, }, 7, 0, "", "",
796"62 03 35 47 38 d0 12 \tvinserti32x4 $0x12,%xmm24,%zmm25,%zmm26{%k7}",},
797{{0x62, 0x03, 0xb5, 0x47, 0x38, 0xd0, 0x12, }, 7, 0, "", "",
798"62 03 b5 47 38 d0 12 \tvinserti64x2 $0x12,%xmm24,%zmm25,%zmm26{%k7}",},
799{{0xc4, 0xe3, 0x7d, 0x39, 0xe6, 0x05, }, 6, 0, "", "",
800"c4 e3 7d 39 e6 05 \tvextracti128 $0x5,%ymm4,%xmm6",},
801{{0x62, 0x03, 0x7d, 0x4f, 0x39, 0xca, 0x12, }, 7, 0, "", "",
802"62 03 7d 4f 39 ca 12 \tvextracti32x4 $0x12,%zmm25,%xmm26{%k7}",},
803{{0x62, 0x03, 0xfd, 0x4f, 0x39, 0xca, 0x12, }, 7, 0, "", "",
804"62 03 fd 4f 39 ca 12 \tvextracti64x2 $0x12,%zmm25,%xmm26{%k7}",},
805{{0x62, 0x03, 0x15, 0x47, 0x3a, 0xf4, 0x12, }, 7, 0, "", "",
806"62 03 15 47 3a f4 12 \tvinserti32x8 $0x12,%ymm28,%zmm29,%zmm30{%k7}",},
807{{0x62, 0x03, 0xad, 0x47, 0x3a, 0xd9, 0x12, }, 7, 0, "", "",
808"62 03 ad 47 3a d9 12 \tvinserti64x4 $0x12,%ymm25,%zmm26,%zmm27{%k7}",},
809{{0x62, 0x03, 0x7d, 0x4f, 0x3b, 0xee, 0x12, }, 7, 0, "", "",
810"62 03 7d 4f 3b ee 12 \tvextracti32x8 $0x12,%zmm29,%ymm30{%k7}",},
811{{0x62, 0x03, 0xfd, 0x4f, 0x3b, 0xd3, 0x12, }, 7, 0, "", "",
812"62 03 fd 4f 3b d3 12 \tvextracti64x4 $0x12,%zmm26,%ymm27{%k7}",},
813{{0x62, 0x93, 0x0d, 0x40, 0x3e, 0xed, 0x12, }, 7, 0, "", "",
814"62 93 0d 40 3e ed 12 \tvpcmpub $0x12,%zmm29,%zmm30,%k5",},
815{{0x62, 0x93, 0xa5, 0x40, 0x3e, 0xea, 0x12, }, 7, 0, "", "",
816"62 93 a5 40 3e ea 12 \tvpcmpuw $0x12,%zmm26,%zmm27,%k5",},
817{{0x62, 0x93, 0x0d, 0x40, 0x3f, 0xed, 0x12, }, 7, 0, "", "",
818"62 93 0d 40 3f ed 12 \tvpcmpb $0x12,%zmm29,%zmm30,%k5",},
819{{0x62, 0x93, 0xa5, 0x40, 0x3f, 0xea, 0x12, }, 7, 0, "", "",
820"62 93 a5 40 3f ea 12 \tvpcmpw $0x12,%zmm26,%zmm27,%k5",},
821{{0xc4, 0xe3, 0x4d, 0x42, 0xd4, 0x05, }, 6, 0, "", "",
822"c4 e3 4d 42 d4 05 \tvmpsadbw $0x5,%ymm4,%ymm6,%ymm2",},
823{{0x62, 0xf3, 0x55, 0x48, 0x42, 0xf4, 0x12, }, 7, 0, "", "",
824"62 f3 55 48 42 f4 12 \tvdbpsadbw $0x12,%zmm4,%zmm5,%zmm6",},
825{{0x62, 0x03, 0x2d, 0x40, 0x43, 0xd9, 0x12, }, 7, 0, "", "",
826"62 03 2d 40 43 d9 12 \tvshufi32x4 $0x12,%zmm25,%zmm26,%zmm27",},
827{{0x62, 0x03, 0x95, 0x40, 0x43, 0xf4, 0x12, }, 7, 0, "", "",
828"62 03 95 40 43 f4 12 \tvshufi64x2 $0x12,%zmm28,%zmm29,%zmm30",},
829{{0x62, 0x03, 0x2d, 0x40, 0x50, 0xd9, 0x12, }, 7, 0, "", "",
830"62 03 2d 40 50 d9 12 \tvrangeps $0x12,%zmm25,%zmm26,%zmm27",},
831{{0x62, 0x03, 0x95, 0x40, 0x50, 0xf4, 0x12, }, 7, 0, "", "",
832"62 03 95 40 50 f4 12 \tvrangepd $0x12,%zmm28,%zmm29,%zmm30",},
833{{0x62, 0x03, 0x2d, 0x00, 0x51, 0xd9, 0x12, }, 7, 0, "", "",
834"62 03 2d 00 51 d9 12 \tvrangess $0x12,%xmm25,%xmm26,%xmm27",},
835{{0x62, 0x03, 0x95, 0x00, 0x51, 0xf4, 0x12, }, 7, 0, "", "",
836"62 03 95 00 51 f4 12 \tvrangesd $0x12,%xmm28,%xmm29,%xmm30",},
837{{0x62, 0x03, 0x15, 0x40, 0x54, 0xf4, 0x12, }, 7, 0, "", "",
838"62 03 15 40 54 f4 12 \tvfixupimmps $0x12,%zmm28,%zmm29,%zmm30",},
839{{0x62, 0x03, 0xad, 0x40, 0x54, 0xd9, 0x12, }, 7, 0, "", "",
840"62 03 ad 40 54 d9 12 \tvfixupimmpd $0x12,%zmm25,%zmm26,%zmm27",},
841{{0x62, 0x03, 0x15, 0x07, 0x55, 0xf4, 0x12, }, 7, 0, "", "",
842"62 03 15 07 55 f4 12 \tvfixupimmss $0x12,%xmm28,%xmm29,%xmm30{%k7}",},
843{{0x62, 0x03, 0xad, 0x07, 0x55, 0xd9, 0x12, }, 7, 0, "", "",
844"62 03 ad 07 55 d9 12 \tvfixupimmsd $0x12,%xmm25,%xmm26,%xmm27{%k7}",},
845{{0x62, 0x03, 0x7d, 0x48, 0x56, 0xda, 0x12, }, 7, 0, "", "",
846"62 03 7d 48 56 da 12 \tvreduceps $0x12,%zmm26,%zmm27",},
847{{0x62, 0x03, 0xfd, 0x48, 0x56, 0xf5, 0x12, }, 7, 0, "", "",
848"62 03 fd 48 56 f5 12 \tvreducepd $0x12,%zmm29,%zmm30",},
849{{0x62, 0x03, 0x2d, 0x00, 0x57, 0xd9, 0x12, }, 7, 0, "", "",
850"62 03 2d 00 57 d9 12 \tvreducess $0x12,%xmm25,%xmm26,%xmm27",},
851{{0x62, 0x03, 0x95, 0x00, 0x57, 0xf4, 0x12, }, 7, 0, "", "",
852"62 03 95 00 57 f4 12 \tvreducesd $0x12,%xmm28,%xmm29,%xmm30",},
853{{0x62, 0x93, 0x7d, 0x48, 0x66, 0xeb, 0x12, }, 7, 0, "", "",
854"62 93 7d 48 66 eb 12 \tvfpclassps $0x12,%zmm27,%k5",},
855{{0x62, 0x93, 0xfd, 0x48, 0x66, 0xee, 0x12, }, 7, 0, "", "",
856"62 93 fd 48 66 ee 12 \tvfpclasspd $0x12,%zmm30,%k5",},
857{{0x62, 0x93, 0x7d, 0x08, 0x67, 0xeb, 0x12, }, 7, 0, "", "",
858"62 93 7d 08 67 eb 12 \tvfpclassss $0x12,%xmm27,%k5",},
859{{0x62, 0x93, 0xfd, 0x08, 0x67, 0xee, 0x12, }, 7, 0, "", "",
860"62 93 fd 08 67 ee 12 \tvfpclasssd $0x12,%xmm30,%k5",},
861{{0x62, 0x91, 0x2d, 0x40, 0x72, 0xc1, 0x12, }, 7, 0, "", "",
862"62 91 2d 40 72 c1 12 \tvprord $0x12,%zmm25,%zmm26",},
863{{0x62, 0x91, 0xad, 0x40, 0x72, 0xc1, 0x12, }, 7, 0, "", "",
864"62 91 ad 40 72 c1 12 \tvprorq $0x12,%zmm25,%zmm26",},
865{{0x62, 0x91, 0x0d, 0x40, 0x72, 0xcd, 0x12, }, 7, 0, "", "",
866"62 91 0d 40 72 cd 12 \tvprold $0x12,%zmm29,%zmm30",},
867{{0x62, 0x91, 0x8d, 0x40, 0x72, 0xcd, 0x12, }, 7, 0, "", "",
868"62 91 8d 40 72 cd 12 \tvprolq $0x12,%zmm29,%zmm30",},
869{{0x0f, 0x72, 0xe6, 0x02, }, 4, 0, "", "",
870"0f 72 e6 02 \tpsrad $0x2,%mm6",},
871{{0xc5, 0xed, 0x72, 0xe6, 0x05, }, 5, 0, "", "",
872"c5 ed 72 e6 05 \tvpsrad $0x5,%ymm6,%ymm2",},
873{{0x62, 0x91, 0x4d, 0x40, 0x72, 0xe2, 0x05, }, 7, 0, "", "",
874"62 91 4d 40 72 e2 05 \tvpsrad $0x5,%zmm26,%zmm22",},
875{{0x62, 0x91, 0xcd, 0x40, 0x72, 0xe2, 0x05, }, 7, 0, "", "",
876"62 91 cd 40 72 e2 05 \tvpsraq $0x5,%zmm26,%zmm22",},
877{{0x62, 0x92, 0x7d, 0x41, 0xc6, 0x8c, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
878"62 92 7d 41 c6 8c fe 7b 00 00 00 \tvgatherpf0dps 0x7b(%r14,%zmm31,8){%k1}",},
879{{0x62, 0x92, 0xfd, 0x41, 0xc6, 0x8c, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
880"62 92 fd 41 c6 8c fe 7b 00 00 00 \tvgatherpf0dpd 0x7b(%r14,%ymm31,8){%k1}",},
881{{0x62, 0x92, 0x7d, 0x41, 0xc6, 0x94, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
882"62 92 7d 41 c6 94 fe 7b 00 00 00 \tvgatherpf1dps 0x7b(%r14,%zmm31,8){%k1}",},
883{{0x62, 0x92, 0xfd, 0x41, 0xc6, 0x94, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
884"62 92 fd 41 c6 94 fe 7b 00 00 00 \tvgatherpf1dpd 0x7b(%r14,%ymm31,8){%k1}",},
885{{0x62, 0x92, 0x7d, 0x41, 0xc6, 0xac, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
886"62 92 7d 41 c6 ac fe 7b 00 00 00 \tvscatterpf0dps 0x7b(%r14,%zmm31,8){%k1}",},
887{{0x62, 0x92, 0xfd, 0x41, 0xc6, 0xac, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
888"62 92 fd 41 c6 ac fe 7b 00 00 00 \tvscatterpf0dpd 0x7b(%r14,%ymm31,8){%k1}",},
889{{0x62, 0x92, 0x7d, 0x41, 0xc6, 0xb4, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
890"62 92 7d 41 c6 b4 fe 7b 00 00 00 \tvscatterpf1dps 0x7b(%r14,%zmm31,8){%k1}",},
891{{0x62, 0x92, 0xfd, 0x41, 0xc6, 0xb4, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
892"62 92 fd 41 c6 b4 fe 7b 00 00 00 \tvscatterpf1dpd 0x7b(%r14,%ymm31,8){%k1}",},
893{{0x62, 0x92, 0x7d, 0x41, 0xc7, 0x8c, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
894"62 92 7d 41 c7 8c fe 7b 00 00 00 \tvgatherpf0qps 0x7b(%r14,%zmm31,8){%k1}",},
895{{0x62, 0x92, 0xfd, 0x41, 0xc7, 0x8c, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
896"62 92 fd 41 c7 8c fe 7b 00 00 00 \tvgatherpf0qpd 0x7b(%r14,%zmm31,8){%k1}",},
897{{0x62, 0x92, 0x7d, 0x41, 0xc7, 0x94, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
898"62 92 7d 41 c7 94 fe 7b 00 00 00 \tvgatherpf1qps 0x7b(%r14,%zmm31,8){%k1}",},
899{{0x62, 0x92, 0xfd, 0x41, 0xc7, 0x94, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
900"62 92 fd 41 c7 94 fe 7b 00 00 00 \tvgatherpf1qpd 0x7b(%r14,%zmm31,8){%k1}",},
901{{0x62, 0x92, 0x7d, 0x41, 0xc7, 0xac, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
902"62 92 7d 41 c7 ac fe 7b 00 00 00 \tvscatterpf0qps 0x7b(%r14,%zmm31,8){%k1}",},
903{{0x62, 0x92, 0xfd, 0x41, 0xc7, 0xac, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
904"62 92 fd 41 c7 ac fe 7b 00 00 00 \tvscatterpf0qpd 0x7b(%r14,%zmm31,8){%k1}",},
905{{0x62, 0x92, 0x7d, 0x41, 0xc7, 0xb4, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
906"62 92 7d 41 c7 b4 fe 7b 00 00 00 \tvscatterpf1qps 0x7b(%r14,%zmm31,8){%k1}",},
907{{0x62, 0x92, 0xfd, 0x41, 0xc7, 0xb4, 0xfe, 0x7b, 0x00, 0x00, 0x00, }, 11, 0, "", "",
908"62 92 fd 41 c7 b4 fe 7b 00 00 00 \tvscatterpf1qpd 0x7b(%r14,%zmm31,8){%k1}",},
909{{0x62, 0x01, 0x95, 0x40, 0x58, 0xf4, }, 6, 0, "", "",
910"62 01 95 40 58 f4 \tvaddpd %zmm28,%zmm29,%zmm30",},
911{{0x62, 0x01, 0x95, 0x47, 0x58, 0xf4, }, 6, 0, "", "",
912"62 01 95 47 58 f4 \tvaddpd %zmm28,%zmm29,%zmm30{%k7}",},
913{{0x62, 0x01, 0x95, 0xc7, 0x58, 0xf4, }, 6, 0, "", "",
914"62 01 95 c7 58 f4 \tvaddpd %zmm28,%zmm29,%zmm30{%k7}{z}",},
915{{0x62, 0x01, 0x95, 0x10, 0x58, 0xf4, }, 6, 0, "", "",
916"62 01 95 10 58 f4 \tvaddpd {rn-sae},%zmm28,%zmm29,%zmm30",},
917{{0x62, 0x01, 0x95, 0x50, 0x58, 0xf4, }, 6, 0, "", "",
918"62 01 95 50 58 f4 \tvaddpd {ru-sae},%zmm28,%zmm29,%zmm30",},
919{{0x62, 0x01, 0x95, 0x30, 0x58, 0xf4, }, 6, 0, "", "",
920"62 01 95 30 58 f4 \tvaddpd {rd-sae},%zmm28,%zmm29,%zmm30",},
921{{0x62, 0x01, 0x95, 0x70, 0x58, 0xf4, }, 6, 0, "", "",
922"62 01 95 70 58 f4 \tvaddpd {rz-sae},%zmm28,%zmm29,%zmm30",},
923{{0x62, 0x61, 0x95, 0x40, 0x58, 0x31, }, 6, 0, "", "",
924"62 61 95 40 58 31 \tvaddpd (%rcx),%zmm29,%zmm30",},
925{{0x62, 0x21, 0x95, 0x40, 0x58, 0xb4, 0xf0, 0x23, 0x01, 0x00, 0x00, }, 11, 0, "", "",
926"62 21 95 40 58 b4 f0 23 01 00 00 \tvaddpd 0x123(%rax,%r14,8),%zmm29,%zmm30",},
927{{0x62, 0x61, 0x95, 0x50, 0x58, 0x31, }, 6, 0, "", "",
928"62 61 95 50 58 31 \tvaddpd (%rcx){1to8},%zmm29,%zmm30",},
929{{0x62, 0x61, 0x95, 0x40, 0x58, 0x72, 0x7f, }, 7, 0, "", "",
930"62 61 95 40 58 72 7f \tvaddpd 0x1fc0(%rdx),%zmm29,%zmm30",},
931{{0x62, 0x61, 0x95, 0x50, 0x58, 0x72, 0x7f, }, 7, 0, "", "",
932"62 61 95 50 58 72 7f \tvaddpd 0x3f8(%rdx){1to8},%zmm29,%zmm30",},
933{{0x62, 0xf1, 0x0c, 0x50, 0xc2, 0x6a, 0x7f, 0x08, }, 8, 0, "", "",
934"62 f1 0c 50 c2 6a 7f 08 \tvcmpeq_uqps 0x1fc(%rdx){1to16},%zmm30,%k5",},
935{{0x62, 0xb1, 0x97, 0x07, 0xc2, 0xac, 0xf0, 0x23, 0x01, 0x00, 0x00, 0x01, }, 12, 0, "", "",
936"62 b1 97 07 c2 ac f0 23 01 00 00 01 \tvcmpltsd 0x123(%rax,%r14,8),%xmm29,%k5{%k7}",},
937{{0x62, 0x91, 0x97, 0x17, 0xc2, 0xec, 0x02, }, 7, 0, "", "",
938"62 91 97 17 c2 ec 02 \tvcmplesd {sae},%xmm28,%xmm29,%k5{%k7}",},
939{{0x62, 0x23, 0x15, 0x07, 0x27, 0xb4, 0xf0, 0x23, 0x01, 0x00, 0x00, 0x5b, }, 12, 0, "", "",
940"62 23 15 07 27 b4 f0 23 01 00 00 5b \tvgetmantss $0x5b,0x123(%rax,%r14,8),%xmm29,%xmm30{%k7}",},
9{{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "", 941{{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
10"f3 0f 1b 00 \tbndmk (%rax),%bnd0",}, 942"f3 0f 1b 00 \tbndmk (%rax),%bnd0",},
11{{0xf3, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "", 943{{0xf3, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "",
@@ -325,19 +1257,19 @@
325{{0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "", 1257{{0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
326"0f 1b 84 08 78 56 34 12 \tbndstx %bnd0,0x12345678(%rax,%rcx,1)",}, 1258"0f 1b 84 08 78 56 34 12 \tbndstx %bnd0,0x12345678(%rax,%rcx,1)",},
327{{0xf2, 0xe8, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "call", "unconditional", 1259{{0xf2, 0xe8, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "call", "unconditional",
328"f2 e8 00 00 00 00 \tbnd callq 3f6 <main+0x3f6>",}, 1260"f2 e8 00 00 00 00 \tbnd callq f22 <main+0xf22>",},
329{{0x67, 0xf2, 0xff, 0x10, }, 4, 0, "call", "indirect", 1261{{0x67, 0xf2, 0xff, 0x10, }, 4, 0, "call", "indirect",
330"67 f2 ff 10 \tbnd callq *(%eax)",}, 1262"67 f2 ff 10 \tbnd callq *(%eax)",},
331{{0xf2, 0xc3, }, 2, 0, "ret", "indirect", 1263{{0xf2, 0xc3, }, 2, 0, "ret", "indirect",
332"f2 c3 \tbnd retq ",}, 1264"f2 c3 \tbnd retq ",},
333{{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional", 1265{{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional",
334"f2 e9 00 00 00 00 \tbnd jmpq 402 <main+0x402>",}, 1266"f2 e9 00 00 00 00 \tbnd jmpq f2e <main+0xf2e>",},
335{{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional", 1267{{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional",
336"f2 e9 00 00 00 00 \tbnd jmpq 408 <main+0x408>",}, 1268"f2 e9 00 00 00 00 \tbnd jmpq f34 <main+0xf34>",},
337{{0x67, 0xf2, 0xff, 0x21, }, 4, 0, "jmp", "indirect", 1269{{0x67, 0xf2, 0xff, 0x21, }, 4, 0, "jmp", "indirect",
338"67 f2 ff 21 \tbnd jmpq *(%ecx)",}, 1270"67 f2 ff 21 \tbnd jmpq *(%ecx)",},
339{{0xf2, 0x0f, 0x85, 0x00, 0x00, 0x00, 0x00, }, 7, 0, "jcc", "conditional", 1271{{0xf2, 0x0f, 0x85, 0x00, 0x00, 0x00, 0x00, }, 7, 0, "jcc", "conditional",
340"f2 0f 85 00 00 00 00 \tbnd jne 413 <main+0x413>",}, 1272"f2 0f 85 00 00 00 00 \tbnd jne f3f <main+0xf3f>",},
341{{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "", 1273{{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "",
342"0f 3a cc c1 00 \tsha1rnds4 $0x0,%xmm1,%xmm0",}, 1274"0f 3a cc c1 00 \tsha1rnds4 $0x0,%xmm1,%xmm0",},
343{{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "", 1275{{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "",
@@ -764,5 +1696,3 @@
764"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%rax,%rcx,8)",}, 1696"0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%rax,%rcx,8)",},
765{{0x41, 0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "", 1697{{0x41, 0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
766"41 0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%r8,%rcx,8)",}, 1698"41 0f c7 9c c8 78 56 34 12 \txrstors 0x12345678(%r8,%rcx,8)",},
767{{0x66, 0x0f, 0xae, 0xf8, }, 4, 0, "", "",
768"66 0f ae f8 \tpcommit ",},
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-src.c b/tools/perf/arch/x86/tests/insn-x86-dat-src.c
index 41b1b1c62660..979487dae8d4 100644
--- a/tools/perf/arch/x86/tests/insn-x86-dat-src.c
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-src.c
@@ -19,8 +19,882 @@ int main(void)
19 /* Following line is a marker for the awk script - do not change */ 19 /* Following line is a marker for the awk script - do not change */
20 asm volatile("rdtsc"); /* Start here */ 20 asm volatile("rdtsc"); /* Start here */
21 21
22 /* Test fix for vcvtph2ps in x86-opcode-map.txt */
23
24 asm volatile("vcvtph2ps %xmm3,%ymm5");
25
22#ifdef __x86_64__ 26#ifdef __x86_64__
23 27
28 /* AVX-512: Instructions with the same op codes as Mask Instructions */
29
30 asm volatile("cmovno %rax,%rbx");
31 asm volatile("cmovno 0x12345678(%rax),%rcx");
32 asm volatile("cmovno 0x12345678(%rax),%cx");
33
34 asm volatile("cmove %rax,%rbx");
35 asm volatile("cmove 0x12345678(%rax),%rcx");
36 asm volatile("cmove 0x12345678(%rax),%cx");
37
38 asm volatile("seto 0x12345678(%rax)");
39 asm volatile("setno 0x12345678(%rax)");
40 asm volatile("setb 0x12345678(%rax)");
41 asm volatile("setc 0x12345678(%rax)");
42 asm volatile("setnae 0x12345678(%rax)");
43 asm volatile("setae 0x12345678(%rax)");
44 asm volatile("setnb 0x12345678(%rax)");
45 asm volatile("setnc 0x12345678(%rax)");
46 asm volatile("sets 0x12345678(%rax)");
47 asm volatile("setns 0x12345678(%rax)");
48
49 /* AVX-512: Mask Instructions */
50
51 asm volatile("kandw %k7,%k6,%k5");
52 asm volatile("kandq %k7,%k6,%k5");
53 asm volatile("kandb %k7,%k6,%k5");
54 asm volatile("kandd %k7,%k6,%k5");
55
56 asm volatile("kandnw %k7,%k6,%k5");
57 asm volatile("kandnq %k7,%k6,%k5");
58 asm volatile("kandnb %k7,%k6,%k5");
59 asm volatile("kandnd %k7,%k6,%k5");
60
61 asm volatile("knotw %k7,%k6");
62 asm volatile("knotq %k7,%k6");
63 asm volatile("knotb %k7,%k6");
64 asm volatile("knotd %k7,%k6");
65
66 asm volatile("korw %k7,%k6,%k5");
67 asm volatile("korq %k7,%k6,%k5");
68 asm volatile("korb %k7,%k6,%k5");
69 asm volatile("kord %k7,%k6,%k5");
70
71 asm volatile("kxnorw %k7,%k6,%k5");
72 asm volatile("kxnorq %k7,%k6,%k5");
73 asm volatile("kxnorb %k7,%k6,%k5");
74 asm volatile("kxnord %k7,%k6,%k5");
75
76 asm volatile("kxorw %k7,%k6,%k5");
77 asm volatile("kxorq %k7,%k6,%k5");
78 asm volatile("kxorb %k7,%k6,%k5");
79 asm volatile("kxord %k7,%k6,%k5");
80
81 asm volatile("kaddw %k7,%k6,%k5");
82 asm volatile("kaddq %k7,%k6,%k5");
83 asm volatile("kaddb %k7,%k6,%k5");
84 asm volatile("kaddd %k7,%k6,%k5");
85
86 asm volatile("kunpckbw %k7,%k6,%k5");
87 asm volatile("kunpckwd %k7,%k6,%k5");
88 asm volatile("kunpckdq %k7,%k6,%k5");
89
90 asm volatile("kmovw %k6,%k5");
91 asm volatile("kmovw (%rcx),%k5");
92 asm volatile("kmovw 0x123(%rax,%r14,8),%k5");
93 asm volatile("kmovw %k5,(%rcx)");
94 asm volatile("kmovw %k5,0x123(%rax,%r14,8)");
95 asm volatile("kmovw %eax,%k5");
96 asm volatile("kmovw %ebp,%k5");
97 asm volatile("kmovw %r13d,%k5");
98 asm volatile("kmovw %k5,%eax");
99 asm volatile("kmovw %k5,%ebp");
100 asm volatile("kmovw %k5,%r13d");
101
102 asm volatile("kmovq %k6,%k5");
103 asm volatile("kmovq (%rcx),%k5");
104 asm volatile("kmovq 0x123(%rax,%r14,8),%k5");
105 asm volatile("kmovq %k5,(%rcx)");
106 asm volatile("kmovq %k5,0x123(%rax,%r14,8)");
107 asm volatile("kmovq %rax,%k5");
108 asm volatile("kmovq %rbp,%k5");
109 asm volatile("kmovq %r13,%k5");
110 asm volatile("kmovq %k5,%rax");
111 asm volatile("kmovq %k5,%rbp");
112 asm volatile("kmovq %k5,%r13");
113
114 asm volatile("kmovb %k6,%k5");
115 asm volatile("kmovb (%rcx),%k5");
116 asm volatile("kmovb 0x123(%rax,%r14,8),%k5");
117 asm volatile("kmovb %k5,(%rcx)");
118 asm volatile("kmovb %k5,0x123(%rax,%r14,8)");
119 asm volatile("kmovb %eax,%k5");
120 asm volatile("kmovb %ebp,%k5");
121 asm volatile("kmovb %r13d,%k5");
122 asm volatile("kmovb %k5,%eax");
123 asm volatile("kmovb %k5,%ebp");
124 asm volatile("kmovb %k5,%r13d");
125
126 asm volatile("kmovd %k6,%k5");
127 asm volatile("kmovd (%rcx),%k5");
128 asm volatile("kmovd 0x123(%rax,%r14,8),%k5");
129 asm volatile("kmovd %k5,(%rcx)");
130 asm volatile("kmovd %k5,0x123(%rax,%r14,8)");
131 asm volatile("kmovd %eax,%k5");
132 asm volatile("kmovd %ebp,%k5");
133 asm volatile("kmovd %r13d,%k5");
134 asm volatile("kmovd %k5,%eax");
135 asm volatile("kmovd %k5,%ebp");
136 asm volatile("kmovd %k5,%r13d");
137
138 asm volatile("kortestw %k6,%k5");
139 asm volatile("kortestq %k6,%k5");
140 asm volatile("kortestb %k6,%k5");
141 asm volatile("kortestd %k6,%k5");
142
143 asm volatile("ktestw %k6,%k5");
144 asm volatile("ktestq %k6,%k5");
145 asm volatile("ktestb %k6,%k5");
146 asm volatile("ktestd %k6,%k5");
147
148 asm volatile("kshiftrw $0x12,%k6,%k5");
149 asm volatile("kshiftrq $0x5b,%k6,%k5");
150 asm volatile("kshiftlw $0x12,%k6,%k5");
151 asm volatile("kshiftlq $0x5b,%k6,%k5");
152
153 /* AVX-512: Op code 0f 5b */
154 asm volatile("vcvtdq2ps %xmm5,%xmm6");
155 asm volatile("vcvtqq2ps %zmm29,%ymm6{%k7}");
156 asm volatile("vcvtps2dq %xmm5,%xmm6");
157 asm volatile("vcvttps2dq %xmm5,%xmm6");
158
159 /* AVX-512: Op code 0f 6f */
160
161 asm volatile("movq %mm0,%mm4");
162 asm volatile("vmovdqa %ymm4,%ymm6");
163 asm volatile("vmovdqa32 %zmm25,%zmm26");
164 asm volatile("vmovdqa64 %zmm25,%zmm26");
165 asm volatile("vmovdqu %ymm4,%ymm6");
166 asm volatile("vmovdqu32 %zmm29,%zmm30");
167 asm volatile("vmovdqu64 %zmm25,%zmm26");
168 asm volatile("vmovdqu8 %zmm29,%zmm30");
169 asm volatile("vmovdqu16 %zmm25,%zmm26");
170
171 /* AVX-512: Op code 0f 78 */
172
173 asm volatile("vmread %rax,%rbx");
174 asm volatile("vcvttps2udq %zmm25,%zmm26");
175 asm volatile("vcvttpd2udq %zmm29,%ymm6{%k7}");
176 asm volatile("vcvttsd2usi %xmm6,%rax");
177 asm volatile("vcvttss2usi %xmm6,%rax");
178 asm volatile("vcvttps2uqq %ymm5,%zmm26{%k7}");
179 asm volatile("vcvttpd2uqq %zmm29,%zmm30");
180
181 /* AVX-512: Op code 0f 79 */
182
183 asm volatile("vmwrite %rax,%rbx");
184 asm volatile("vcvtps2udq %zmm25,%zmm26");
185 asm volatile("vcvtpd2udq %zmm29,%ymm6{%k7}");
186 asm volatile("vcvtsd2usi %xmm6,%rax");
187 asm volatile("vcvtss2usi %xmm6,%rax");
188 asm volatile("vcvtps2uqq %ymm5,%zmm26{%k7}");
189 asm volatile("vcvtpd2uqq %zmm29,%zmm30");
190
191 /* AVX-512: Op code 0f 7a */
192
193 asm volatile("vcvtudq2pd %ymm5,%zmm29{%k7}");
194 asm volatile("vcvtuqq2pd %zmm25,%zmm26");
195 asm volatile("vcvtudq2ps %zmm29,%zmm30");
196 asm volatile("vcvtuqq2ps %zmm25,%ymm26{%k7}");
197 asm volatile("vcvttps2qq %ymm25,%zmm26{%k7}");
198 asm volatile("vcvttpd2qq %zmm29,%zmm30");
199
200 /* AVX-512: Op code 0f 7b */
201
202 asm volatile("vcvtusi2sd %eax,%xmm5,%xmm6");
203 asm volatile("vcvtusi2ss %eax,%xmm5,%xmm6");
204 asm volatile("vcvtps2qq %ymm5,%zmm26{%k7}");
205 asm volatile("vcvtpd2qq %zmm29,%zmm30");
206
207 /* AVX-512: Op code 0f 7f */
208
209 asm volatile("movq.s %mm0,%mm4");
210 asm volatile("vmovdqa %ymm8,%ymm6");
211 asm volatile("vmovdqa32.s %zmm25,%zmm26");
212 asm volatile("vmovdqa64.s %zmm25,%zmm26");
213 asm volatile("vmovdqu %ymm8,%ymm6");
214 asm volatile("vmovdqu32.s %zmm25,%zmm26");
215 asm volatile("vmovdqu64.s %zmm25,%zmm26");
216 asm volatile("vmovdqu8.s %zmm30,(%rcx)");
217 asm volatile("vmovdqu16.s %zmm25,%zmm26");
218
219 /* AVX-512: Op code 0f db */
220
221 asm volatile("pand %mm1,%mm2");
222 asm volatile("pand %xmm1,%xmm2");
223 asm volatile("vpand %ymm4,%ymm6,%ymm2");
224 asm volatile("vpandd %zmm24,%zmm25,%zmm26");
225 asm volatile("vpandq %zmm24,%zmm25,%zmm26");
226
227 /* AVX-512: Op code 0f df */
228
229 asm volatile("pandn %mm1,%mm2");
230 asm volatile("pandn %xmm1,%xmm2");
231 asm volatile("vpandn %ymm4,%ymm6,%ymm2");
232 asm volatile("vpandnd %zmm24,%zmm25,%zmm26");
233 asm volatile("vpandnq %zmm24,%zmm25,%zmm26");
234
235 /* AVX-512: Op code 0f e6 */
236
237 asm volatile("vcvttpd2dq %xmm1,%xmm2");
238 asm volatile("vcvtdq2pd %xmm5,%xmm6");
239 asm volatile("vcvtdq2pd %ymm5,%zmm26{%k7}");
240 asm volatile("vcvtqq2pd %zmm25,%zmm26");
241 asm volatile("vcvtpd2dq %xmm1,%xmm2");
242
243 /* AVX-512: Op code 0f eb */
244
245 asm volatile("por %mm4,%mm6");
246 asm volatile("vpor %ymm4,%ymm6,%ymm2");
247 asm volatile("vpord %zmm24,%zmm25,%zmm26");
248 asm volatile("vporq %zmm24,%zmm25,%zmm26");
249
250 /* AVX-512: Op code 0f ef */
251
252 asm volatile("pxor %mm4,%mm6");
253 asm volatile("vpxor %ymm4,%ymm6,%ymm2");
254 asm volatile("vpxord %zmm24,%zmm25,%zmm26");
255 asm volatile("vpxorq %zmm24,%zmm25,%zmm26");
256
257 /* AVX-512: Op code 0f 38 10 */
258
259 asm volatile("pblendvb %xmm1,%xmm0");
260 asm volatile("vpsrlvw %zmm27,%zmm28,%zmm29");
261 asm volatile("vpmovuswb %zmm28,%ymm6{%k7}");
262
263 /* AVX-512: Op code 0f 38 11 */
264
265 asm volatile("vpmovusdb %zmm28,%xmm6{%k7}");
266 asm volatile("vpsravw %zmm27,%zmm28,%zmm29");
267
268 /* AVX-512: Op code 0f 38 12 */
269
270 asm volatile("vpmovusqb %zmm27,%xmm6{%k7}");
271 asm volatile("vpsllvw %zmm27,%zmm28,%zmm29");
272
273 /* AVX-512: Op code 0f 38 13 */
274
275 asm volatile("vcvtph2ps %xmm3,%ymm5");
276 asm volatile("vcvtph2ps %ymm5,%zmm27{%k7}");
277 asm volatile("vpmovusdw %zmm27,%ymm6{%k7}");
278
279 /* AVX-512: Op code 0f 38 14 */
280
281 asm volatile("blendvps %xmm1,%xmm0");
282 asm volatile("vpmovusqw %zmm27,%xmm6{%k7}");
283 asm volatile("vprorvd %zmm27,%zmm28,%zmm29");
284 asm volatile("vprorvq %zmm27,%zmm28,%zmm29");
285
286 /* AVX-512: Op code 0f 38 15 */
287
288 asm volatile("blendvpd %xmm1,%xmm0");
289 asm volatile("vpmovusqd %zmm27,%ymm6{%k7}");
290 asm volatile("vprolvd %zmm27,%zmm28,%zmm29");
291 asm volatile("vprolvq %zmm27,%zmm28,%zmm29");
292
293 /* AVX-512: Op code 0f 38 16 */
294
295 asm volatile("vpermps %ymm4,%ymm6,%ymm2");
296 asm volatile("vpermps %ymm24,%ymm26,%ymm22{%k7}");
297 asm volatile("vpermpd %ymm24,%ymm26,%ymm22{%k7}");
298
299 /* AVX-512: Op code 0f 38 19 */
300
301 asm volatile("vbroadcastsd %xmm4,%ymm6");
302 asm volatile("vbroadcastf32x2 %xmm27,%zmm26");
303
304 /* AVX-512: Op code 0f 38 1a */
305
306 asm volatile("vbroadcastf128 (%rcx),%ymm4");
307 asm volatile("vbroadcastf32x4 (%rcx),%zmm26");
308 asm volatile("vbroadcastf64x2 (%rcx),%zmm26");
309
310 /* AVX-512: Op code 0f 38 1b */
311
312 asm volatile("vbroadcastf32x8 (%rcx),%zmm27");
313 asm volatile("vbroadcastf64x4 (%rcx),%zmm26");
314
315 /* AVX-512: Op code 0f 38 1f */
316
317 asm volatile("vpabsq %zmm27,%zmm28");
318
319 /* AVX-512: Op code 0f 38 20 */
320
321 asm volatile("vpmovsxbw %xmm4,%xmm5");
322 asm volatile("vpmovswb %zmm27,%ymm6{%k7}");
323
324 /* AVX-512: Op code 0f 38 21 */
325
326 asm volatile("vpmovsxbd %xmm4,%ymm6");
327 asm volatile("vpmovsdb %zmm27,%xmm6{%k7}");
328
329 /* AVX-512: Op code 0f 38 22 */
330
331 asm volatile("vpmovsxbq %xmm4,%ymm4");
332 asm volatile("vpmovsqb %zmm27,%xmm6{%k7}");
333
334 /* AVX-512: Op code 0f 38 23 */
335
336 asm volatile("vpmovsxwd %xmm4,%ymm4");
337 asm volatile("vpmovsdw %zmm27,%ymm6{%k7}");
338
339 /* AVX-512: Op code 0f 38 24 */
340
341 asm volatile("vpmovsxwq %xmm4,%ymm6");
342 asm volatile("vpmovsqw %zmm27,%xmm6{%k7}");
343
344 /* AVX-512: Op code 0f 38 25 */
345
346 asm volatile("vpmovsxdq %xmm4,%ymm4");
347 asm volatile("vpmovsqd %zmm27,%ymm6{%k7}");
348
349 /* AVX-512: Op code 0f 38 26 */
350
351 asm volatile("vptestmb %zmm27,%zmm28,%k5");
352 asm volatile("vptestmw %zmm27,%zmm28,%k5");
353 asm volatile("vptestnmb %zmm26,%zmm27,%k5");
354 asm volatile("vptestnmw %zmm26,%zmm27,%k5");
355
356 /* AVX-512: Op code 0f 38 27 */
357
358 asm volatile("vptestmd %zmm27,%zmm28,%k5");
359 asm volatile("vptestmq %zmm27,%zmm28,%k5");
360 asm volatile("vptestnmd %zmm26,%zmm27,%k5");
361 asm volatile("vptestnmq %zmm26,%zmm27,%k5");
362
363 /* AVX-512: Op code 0f 38 28 */
364
365 asm volatile("vpmuldq %ymm4,%ymm6,%ymm2");
366 asm volatile("vpmovm2b %k5,%zmm28");
367 asm volatile("vpmovm2w %k5,%zmm28");
368
369 /* AVX-512: Op code 0f 38 29 */
370
371 asm volatile("vpcmpeqq %ymm4,%ymm6,%ymm2");
372 asm volatile("vpmovb2m %zmm28,%k5");
373 asm volatile("vpmovw2m %zmm28,%k5");
374
375 /* AVX-512: Op code 0f 38 2a */
376
377 asm volatile("vmovntdqa (%rcx),%ymm4");
378 asm volatile("vpbroadcastmb2q %k6,%zmm30");
379
380 /* AVX-512: Op code 0f 38 2c */
381
382 asm volatile("vmaskmovps (%rcx),%ymm4,%ymm6");
383 asm volatile("vscalefps %zmm24,%zmm25,%zmm26");
384 asm volatile("vscalefpd %zmm24,%zmm25,%zmm26");
385
386 /* AVX-512: Op code 0f 38 2d */
387
388 asm volatile("vmaskmovpd (%rcx),%ymm4,%ymm6");
389 asm volatile("vscalefss %xmm24,%xmm25,%xmm26{%k7}");
390 asm volatile("vscalefsd %xmm24,%xmm25,%xmm26{%k7}");
391
392 /* AVX-512: Op code 0f 38 30 */
393
394 asm volatile("vpmovzxbw %xmm4,%ymm4");
395 asm volatile("vpmovwb %zmm27,%ymm6{%k7}");
396
397 /* AVX-512: Op code 0f 38 31 */
398
399 asm volatile("vpmovzxbd %xmm4,%ymm6");
400 asm volatile("vpmovdb %zmm27,%xmm6{%k7}");
401
402 /* AVX-512: Op code 0f 38 32 */
403
404 asm volatile("vpmovzxbq %xmm4,%ymm4");
405 asm volatile("vpmovqb %zmm27,%xmm6{%k7}");
406
407 /* AVX-512: Op code 0f 38 33 */
408
409 asm volatile("vpmovzxwd %xmm4,%ymm4");
410 asm volatile("vpmovdw %zmm27,%ymm6{%k7}");
411
412 /* AVX-512: Op code 0f 38 34 */
413
414 asm volatile("vpmovzxwq %xmm4,%ymm6");
415 asm volatile("vpmovqw %zmm27,%xmm6{%k7}");
416
417 /* AVX-512: Op code 0f 38 35 */
418
419 asm volatile("vpmovzxdq %xmm4,%ymm4");
420 asm volatile("vpmovqd %zmm27,%ymm6{%k7}");
421
422 /* AVX-512: Op code 0f 38 38 */
423
424 asm volatile("vpermd %ymm4,%ymm6,%ymm2");
425 asm volatile("vpermd %ymm24,%ymm26,%ymm22{%k7}");
426 asm volatile("vpermq %ymm24,%ymm26,%ymm22{%k7}");
427
428 /* AVX-512: Op code 0f 38 38 */
429
430 asm volatile("vpminsb %ymm4,%ymm6,%ymm2");
431 asm volatile("vpmovm2d %k5,%zmm28");
432 asm volatile("vpmovm2q %k5,%zmm28");
433
434 /* AVX-512: Op code 0f 38 39 */
435
436 asm volatile("vpminsd %xmm1,%xmm2,%xmm3");
437 asm volatile("vpminsd %zmm24,%zmm25,%zmm26");
438 asm volatile("vpminsq %zmm24,%zmm25,%zmm26");
439 asm volatile("vpmovd2m %zmm28,%k5");
440 asm volatile("vpmovq2m %zmm28,%k5");
441
442 /* AVX-512: Op code 0f 38 3a */
443
444 asm volatile("vpminuw %ymm4,%ymm6,%ymm2");
445 asm volatile("vpbroadcastmw2d %k6,%zmm28");
446
447 /* AVX-512: Op code 0f 38 3b */
448
449 asm volatile("vpminud %ymm4,%ymm6,%ymm2");
450 asm volatile("vpminud %zmm24,%zmm25,%zmm26");
451 asm volatile("vpminuq %zmm24,%zmm25,%zmm26");
452
453 /* AVX-512: Op code 0f 38 3d */
454
455 asm volatile("vpmaxsd %ymm4,%ymm6,%ymm2");
456 asm volatile("vpmaxsd %zmm24,%zmm25,%zmm26");
457 asm volatile("vpmaxsq %zmm24,%zmm25,%zmm26");
458
459 /* AVX-512: Op code 0f 38 3f */
460
461 asm volatile("vpmaxud %ymm4,%ymm6,%ymm2");
462 asm volatile("vpmaxud %zmm24,%zmm25,%zmm26");
463 asm volatile("vpmaxuq %zmm24,%zmm25,%zmm26");
464
465 /* AVX-512: Op code 0f 38 42 */
466
467 asm volatile("vpmulld %ymm4,%ymm6,%ymm2");
468 asm volatile("vpmulld %zmm24,%zmm25,%zmm26");
469 asm volatile("vpmullq %zmm24,%zmm25,%zmm26");
470
471 /* AVX-512: Op code 0f 38 42 */
472
473 asm volatile("vgetexpps %zmm25,%zmm26");
474 asm volatile("vgetexppd %zmm27,%zmm28");
475
476 /* AVX-512: Op code 0f 38 43 */
477
478 asm volatile("vgetexpss %xmm24,%xmm25,%xmm26{%k7}");
479 asm volatile("vgetexpsd %xmm28,%xmm29,%xmm30{%k7}");
480
481 /* AVX-512: Op code 0f 38 44 */
482
483 asm volatile("vplzcntd %zmm27,%zmm28");
484 asm volatile("vplzcntq %zmm27,%zmm28");
485
486 /* AVX-512: Op code 0f 38 46 */
487
488 asm volatile("vpsravd %ymm4,%ymm6,%ymm2");
489 asm volatile("vpsravd %zmm24,%zmm25,%zmm26");
490 asm volatile("vpsravq %zmm24,%zmm25,%zmm26");
491
492 /* AVX-512: Op code 0f 38 4c */
493
494 asm volatile("vrcp14ps %zmm25,%zmm26");
495 asm volatile("vrcp14pd %zmm27,%zmm28");
496
497 /* AVX-512: Op code 0f 38 4d */
498
499 asm volatile("vrcp14ss %xmm24,%xmm25,%xmm26{%k7}");
500 asm volatile("vrcp14sd %xmm24,%xmm25,%xmm26{%k7}");
501
502 /* AVX-512: Op code 0f 38 4e */
503
504 asm volatile("vrsqrt14ps %zmm25,%zmm26");
505 asm volatile("vrsqrt14pd %zmm27,%zmm28");
506
507 /* AVX-512: Op code 0f 38 4f */
508
509 asm volatile("vrsqrt14ss %xmm24,%xmm25,%xmm26{%k7}");
510 asm volatile("vrsqrt14sd %xmm24,%xmm25,%xmm26{%k7}");
511
512 /* AVX-512: Op code 0f 38 59 */
513
514 asm volatile("vpbroadcastq %xmm4,%xmm6");
515 asm volatile("vbroadcasti32x2 %xmm27,%zmm26");
516
517 /* AVX-512: Op code 0f 38 5a */
518
519 asm volatile("vbroadcasti128 (%rcx),%ymm4");
520 asm volatile("vbroadcasti32x4 (%rcx),%zmm26");
521 asm volatile("vbroadcasti64x2 (%rcx),%zmm26");
522
523 /* AVX-512: Op code 0f 38 5b */
524
525 asm volatile("vbroadcasti32x8 (%rcx),%zmm28");
526 asm volatile("vbroadcasti64x4 (%rcx),%zmm26");
527
528 /* AVX-512: Op code 0f 38 64 */
529
530 asm volatile("vpblendmd %zmm26,%zmm27,%zmm28");
531 asm volatile("vpblendmq %zmm26,%zmm27,%zmm28");
532
533 /* AVX-512: Op code 0f 38 65 */
534
535 asm volatile("vblendmps %zmm24,%zmm25,%zmm26");
536 asm volatile("vblendmpd %zmm26,%zmm27,%zmm28");
537
538 /* AVX-512: Op code 0f 38 66 */
539
540 asm volatile("vpblendmb %zmm26,%zmm27,%zmm28");
541 asm volatile("vpblendmw %zmm26,%zmm27,%zmm28");
542
543 /* AVX-512: Op code 0f 38 75 */
544
545 asm volatile("vpermi2b %zmm24,%zmm25,%zmm26");
546 asm volatile("vpermi2w %zmm26,%zmm27,%zmm28");
547
548 /* AVX-512: Op code 0f 38 76 */
549
550 asm volatile("vpermi2d %zmm26,%zmm27,%zmm28");
551 asm volatile("vpermi2q %zmm26,%zmm27,%zmm28");
552
553 /* AVX-512: Op code 0f 38 77 */
554
555 asm volatile("vpermi2ps %zmm26,%zmm27,%zmm28");
556 asm volatile("vpermi2pd %zmm26,%zmm27,%zmm28");
557
558 /* AVX-512: Op code 0f 38 7a */
559
560 asm volatile("vpbroadcastb %eax,%xmm30");
561
562 /* AVX-512: Op code 0f 38 7b */
563
564 asm volatile("vpbroadcastw %eax,%xmm30");
565
566 /* AVX-512: Op code 0f 38 7c */
567
568 asm volatile("vpbroadcastd %eax,%xmm30");
569 asm volatile("vpbroadcastq %rax,%zmm30");
570
571 /* AVX-512: Op code 0f 38 7d */
572
573 asm volatile("vpermt2b %zmm26,%zmm27,%zmm28");
574 asm volatile("vpermt2w %zmm26,%zmm27,%zmm28");
575
576 /* AVX-512: Op code 0f 38 7e */
577
578 asm volatile("vpermt2d %zmm26,%zmm27,%zmm28");
579 asm volatile("vpermt2q %zmm26,%zmm27,%zmm28");
580
581 /* AVX-512: Op code 0f 38 7f */
582
583 asm volatile("vpermt2ps %zmm26,%zmm27,%zmm28");
584 asm volatile("vpermt2pd %zmm26,%zmm27,%zmm28");
585
586 /* AVX-512: Op code 0f 38 83 */
587
588 asm volatile("vpmultishiftqb %zmm26,%zmm27,%zmm28");
589
590 /* AVX-512: Op code 0f 38 88 */
591
592 asm volatile("vexpandps (%rcx),%zmm26");
593 asm volatile("vexpandpd (%rcx),%zmm28");
594
595 /* AVX-512: Op code 0f 38 89 */
596
597 asm volatile("vpexpandd (%rcx),%zmm28");
598 asm volatile("vpexpandq (%rcx),%zmm26");
599
600 /* AVX-512: Op code 0f 38 8a */
601
602 asm volatile("vcompressps %zmm28,(%rcx)");
603 asm volatile("vcompresspd %zmm28,(%rcx)");
604
605 /* AVX-512: Op code 0f 38 8b */
606
607 asm volatile("vpcompressd %zmm28,(%rcx)");
608 asm volatile("vpcompressq %zmm26,(%rcx)");
609
610 /* AVX-512: Op code 0f 38 8d */
611
612 asm volatile("vpermb %zmm26,%zmm27,%zmm28");
613 asm volatile("vpermw %zmm26,%zmm27,%zmm28");
614
615 /* AVX-512: Op code 0f 38 90 */
616
617 asm volatile("vpgatherdd %xmm2,0x02(%rbp,%xmm7,2),%xmm1");
618 asm volatile("vpgatherdq %xmm2,0x04(%rbp,%xmm7,2),%xmm1");
619 asm volatile("vpgatherdd 0x7b(%rbp,%zmm27,8),%zmm26{%k1}");
620 asm volatile("vpgatherdq 0x7b(%rbp,%ymm27,8),%zmm26{%k1}");
621
622 /* AVX-512: Op code 0f 38 91 */
623
624 asm volatile("vpgatherqd %xmm2,0x02(%rbp,%xmm7,2),%xmm1");
625 asm volatile("vpgatherqq %xmm2,0x02(%rbp,%xmm7,2),%xmm1");
626 asm volatile("vpgatherqd 0x7b(%rbp,%zmm27,8),%ymm26{%k1}");
627 asm volatile("vpgatherqq 0x7b(%rbp,%zmm27,8),%zmm26{%k1}");
628
629 /* AVX-512: Op code 0f 38 a0 */
630
631 asm volatile("vpscatterdd %zmm28,0x7b(%rbp,%zmm29,8){%k1}");
632 asm volatile("vpscatterdq %zmm26,0x7b(%rbp,%ymm27,8){%k1}");
633
634 /* AVX-512: Op code 0f 38 a1 */
635
636 asm volatile("vpscatterqd %ymm6,0x7b(%rbp,%zmm29,8){%k1}");
637 asm volatile("vpscatterqq %ymm6,0x7b(%rbp,%ymm27,8){%k1}");
638
639 /* AVX-512: Op code 0f 38 a2 */
640
641 asm volatile("vscatterdps %zmm28,0x7b(%rbp,%zmm29,8){%k1}");
642 asm volatile("vscatterdpd %zmm28,0x7b(%rbp,%ymm27,8){%k1}");
643
644 /* AVX-512: Op code 0f 38 a3 */
645
646 asm volatile("vscatterqps %ymm6,0x7b(%rbp,%zmm29,8){%k1}");
647 asm volatile("vscatterqpd %zmm28,0x7b(%rbp,%zmm29,8){%k1}");
648
649 /* AVX-512: Op code 0f 38 b4 */
650
651 asm volatile("vpmadd52luq %zmm26,%zmm27,%zmm28");
652
653 /* AVX-512: Op code 0f 38 b5 */
654
655 asm volatile("vpmadd52huq %zmm26,%zmm27,%zmm28");
656
657 /* AVX-512: Op code 0f 38 c4 */
658
659 asm volatile("vpconflictd %zmm26,%zmm27");
660 asm volatile("vpconflictq %zmm26,%zmm27");
661
662 /* AVX-512: Op code 0f 38 c8 */
663
664 asm volatile("vexp2ps %zmm29,%zmm30");
665 asm volatile("vexp2pd %zmm26,%zmm27");
666
667 /* AVX-512: Op code 0f 38 ca */
668
669 asm volatile("vrcp28ps %zmm29,%zmm30");
670 asm volatile("vrcp28pd %zmm26,%zmm27");
671
672 /* AVX-512: Op code 0f 38 cb */
673
674 asm volatile("vrcp28ss %xmm28,%xmm29,%xmm30{%k7}");
675 asm volatile("vrcp28sd %xmm25,%xmm26,%xmm27{%k7}");
676
677 /* AVX-512: Op code 0f 38 cc */
678
679 asm volatile("vrsqrt28ps %zmm29,%zmm30");
680 asm volatile("vrsqrt28pd %zmm26,%zmm27");
681
682 /* AVX-512: Op code 0f 38 cd */
683
684 asm volatile("vrsqrt28ss %xmm28,%xmm29,%xmm30{%k7}");
685 asm volatile("vrsqrt28sd %xmm25,%xmm26,%xmm27{%k7}");
686
687 /* AVX-512: Op code 0f 3a 03 */
688
689 asm volatile("valignd $0x12,%zmm28,%zmm29,%zmm30");
690 asm volatile("valignq $0x12,%zmm25,%zmm26,%zmm27");
691
692 /* AVX-512: Op code 0f 3a 08 */
693
694 asm volatile("vroundps $0x5,%ymm6,%ymm2");
695 asm volatile("vrndscaleps $0x12,%zmm25,%zmm26");
696
697 /* AVX-512: Op code 0f 3a 09 */
698
699 asm volatile("vroundpd $0x5,%ymm6,%ymm2");
700 asm volatile("vrndscalepd $0x12,%zmm25,%zmm26");
701
702 /* AVX-512: Op code 0f 3a 1a */
703
704 asm volatile("vroundss $0x5,%xmm4,%xmm6,%xmm2");
705 asm volatile("vrndscaless $0x12,%xmm24,%xmm25,%xmm26{%k7}");
706
707 /* AVX-512: Op code 0f 3a 0b */
708
709 asm volatile("vroundsd $0x5,%xmm4,%xmm6,%xmm2");
710 asm volatile("vrndscalesd $0x12,%xmm24,%xmm25,%xmm26{%k7}");
711
712 /* AVX-512: Op code 0f 3a 18 */
713
714 asm volatile("vinsertf128 $0x5,%xmm4,%ymm4,%ymm6");
715 asm volatile("vinsertf32x4 $0x12,%xmm24,%zmm25,%zmm26{%k7}");
716 asm volatile("vinsertf64x2 $0x12,%xmm24,%zmm25,%zmm26{%k7}");
717
718 /* AVX-512: Op code 0f 3a 19 */
719
720 asm volatile("vextractf128 $0x5,%ymm4,%xmm4");
721 asm volatile("vextractf32x4 $0x12,%zmm25,%xmm26{%k7}");
722 asm volatile("vextractf64x2 $0x12,%zmm25,%xmm26{%k7}");
723
724 /* AVX-512: Op code 0f 3a 1a */
725
726 asm volatile("vinsertf32x8 $0x12,%ymm25,%zmm26,%zmm27{%k7}");
727 asm volatile("vinsertf64x4 $0x12,%ymm28,%zmm29,%zmm30{%k7}");
728
729 /* AVX-512: Op code 0f 3a 1b */
730
731 asm volatile("vextractf32x8 $0x12,%zmm29,%ymm30{%k7}");
732 asm volatile("vextractf64x4 $0x12,%zmm26,%ymm27{%k7}");
733
734 /* AVX-512: Op code 0f 3a 1e */
735
736 asm volatile("vpcmpud $0x12,%zmm29,%zmm30,%k5");
737 asm volatile("vpcmpuq $0x12,%zmm26,%zmm27,%k5");
738
739 /* AVX-512: Op code 0f 3a 1f */
740
741 asm volatile("vpcmpd $0x12,%zmm29,%zmm30,%k5");
742 asm volatile("vpcmpq $0x12,%zmm26,%zmm27,%k5");
743
744 /* AVX-512: Op code 0f 3a 23 */
745
746 asm volatile("vshuff32x4 $0x12,%zmm28,%zmm29,%zmm30");
747 asm volatile("vshuff64x2 $0x12,%zmm25,%zmm26,%zmm27");
748
749 /* AVX-512: Op code 0f 3a 25 */
750
751 asm volatile("vpternlogd $0x12,%zmm28,%zmm29,%zmm30");
752 asm volatile("vpternlogq $0x12,%zmm28,%zmm29,%zmm30");
753
754 /* AVX-512: Op code 0f 3a 26 */
755
756 asm volatile("vgetmantps $0x12,%zmm26,%zmm27");
757 asm volatile("vgetmantpd $0x12,%zmm29,%zmm30");
758
759 /* AVX-512: Op code 0f 3a 27 */
760
761 asm volatile("vgetmantss $0x12,%xmm25,%xmm26,%xmm27{%k7}");
762 asm volatile("vgetmantsd $0x12,%xmm28,%xmm29,%xmm30{%k7}");
763
764 /* AVX-512: Op code 0f 3a 38 */
765
766 asm volatile("vinserti128 $0x5,%xmm4,%ymm4,%ymm6");
767 asm volatile("vinserti32x4 $0x12,%xmm24,%zmm25,%zmm26{%k7}");
768 asm volatile("vinserti64x2 $0x12,%xmm24,%zmm25,%zmm26{%k7}");
769
770 /* AVX-512: Op code 0f 3a 39 */
771
772 asm volatile("vextracti128 $0x5,%ymm4,%xmm6");
773 asm volatile("vextracti32x4 $0x12,%zmm25,%xmm26{%k7}");
774 asm volatile("vextracti64x2 $0x12,%zmm25,%xmm26{%k7}");
775
776 /* AVX-512: Op code 0f 3a 3a */
777
778 asm volatile("vinserti32x8 $0x12,%ymm28,%zmm29,%zmm30{%k7}");
779 asm volatile("vinserti64x4 $0x12,%ymm25,%zmm26,%zmm27{%k7}");
780
781 /* AVX-512: Op code 0f 3a 3b */
782
783 asm volatile("vextracti32x8 $0x12,%zmm29,%ymm30{%k7}");
784 asm volatile("vextracti64x4 $0x12,%zmm26,%ymm27{%k7}");
785
786 /* AVX-512: Op code 0f 3a 3e */
787
788 asm volatile("vpcmpub $0x12,%zmm29,%zmm30,%k5");
789 asm volatile("vpcmpuw $0x12,%zmm26,%zmm27,%k5");
790
791 /* AVX-512: Op code 0f 3a 3f */
792
793 asm volatile("vpcmpb $0x12,%zmm29,%zmm30,%k5");
794 asm volatile("vpcmpw $0x12,%zmm26,%zmm27,%k5");
795
796 /* AVX-512: Op code 0f 3a 43 */
797
798 asm volatile("vmpsadbw $0x5,%ymm4,%ymm6,%ymm2");
799 asm volatile("vdbpsadbw $0x12,%zmm4,%zmm5,%zmm6");
800
801 /* AVX-512: Op code 0f 3a 43 */
802
803 asm volatile("vshufi32x4 $0x12,%zmm25,%zmm26,%zmm27");
804 asm volatile("vshufi64x2 $0x12,%zmm28,%zmm29,%zmm30");
805
806 /* AVX-512: Op code 0f 3a 50 */
807
808 asm volatile("vrangeps $0x12,%zmm25,%zmm26,%zmm27");
809 asm volatile("vrangepd $0x12,%zmm28,%zmm29,%zmm30");
810
811 /* AVX-512: Op code 0f 3a 51 */
812
813 asm volatile("vrangess $0x12,%xmm25,%xmm26,%xmm27");
814 asm volatile("vrangesd $0x12,%xmm28,%xmm29,%xmm30");
815
816 /* AVX-512: Op code 0f 3a 54 */
817
818 asm volatile("vfixupimmps $0x12,%zmm28,%zmm29,%zmm30");
819 asm volatile("vfixupimmpd $0x12,%zmm25,%zmm26,%zmm27");
820
821 /* AVX-512: Op code 0f 3a 55 */
822
823 asm volatile("vfixupimmss $0x12,%xmm28,%xmm29,%xmm30{%k7}");
824 asm volatile("vfixupimmsd $0x12,%xmm25,%xmm26,%xmm27{%k7}");
825
826 /* AVX-512: Op code 0f 3a 56 */
827
828 asm volatile("vreduceps $0x12,%zmm26,%zmm27");
829 asm volatile("vreducepd $0x12,%zmm29,%zmm30");
830
831 /* AVX-512: Op code 0f 3a 57 */
832
833 asm volatile("vreducess $0x12,%xmm25,%xmm26,%xmm27");
834 asm volatile("vreducesd $0x12,%xmm28,%xmm29,%xmm30");
835
836 /* AVX-512: Op code 0f 3a 66 */
837
838 asm volatile("vfpclassps $0x12,%zmm27,%k5");
839 asm volatile("vfpclasspd $0x12,%zmm30,%k5");
840
841 /* AVX-512: Op code 0f 3a 67 */
842
843 asm volatile("vfpclassss $0x12,%xmm27,%k5");
844 asm volatile("vfpclasssd $0x12,%xmm30,%k5");
845
846 /* AVX-512: Op code 0f 72 (Grp13) */
847
848 asm volatile("vprord $0x12,%zmm25,%zmm26");
849 asm volatile("vprorq $0x12,%zmm25,%zmm26");
850 asm volatile("vprold $0x12,%zmm29,%zmm30");
851 asm volatile("vprolq $0x12,%zmm29,%zmm30");
852 asm volatile("psrad $0x2,%mm6");
853 asm volatile("vpsrad $0x5,%ymm6,%ymm2");
854 asm volatile("vpsrad $0x5,%zmm26,%zmm22");
855 asm volatile("vpsraq $0x5,%zmm26,%zmm22");
856
857 /* AVX-512: Op code 0f 38 c6 (Grp18) */
858
859 asm volatile("vgatherpf0dps 0x7b(%r14,%zmm31,8){%k1}");
860 asm volatile("vgatherpf0dpd 0x7b(%r14,%ymm31,8){%k1}");
861 asm volatile("vgatherpf1dps 0x7b(%r14,%zmm31,8){%k1}");
862 asm volatile("vgatherpf1dpd 0x7b(%r14,%ymm31,8){%k1}");
863 asm volatile("vscatterpf0dps 0x7b(%r14,%zmm31,8){%k1}");
864 asm volatile("vscatterpf0dpd 0x7b(%r14,%ymm31,8){%k1}");
865 asm volatile("vscatterpf1dps 0x7b(%r14,%zmm31,8){%k1}");
866 asm volatile("vscatterpf1dpd 0x7b(%r14,%ymm31,8){%k1}");
867
868 /* AVX-512: Op code 0f 38 c7 (Grp19) */
869
870 asm volatile("vgatherpf0qps 0x7b(%r14,%zmm31,8){%k1}");
871 asm volatile("vgatherpf0qpd 0x7b(%r14,%zmm31,8){%k1}");
872 asm volatile("vgatherpf1qps 0x7b(%r14,%zmm31,8){%k1}");
873 asm volatile("vgatherpf1qpd 0x7b(%r14,%zmm31,8){%k1}");
874 asm volatile("vscatterpf0qps 0x7b(%r14,%zmm31,8){%k1}");
875 asm volatile("vscatterpf0qpd 0x7b(%r14,%zmm31,8){%k1}");
876 asm volatile("vscatterpf1qps 0x7b(%r14,%zmm31,8){%k1}");
877 asm volatile("vscatterpf1qpd 0x7b(%r14,%zmm31,8){%k1}");
878
879 /* AVX-512: Examples */
880
881 asm volatile("vaddpd %zmm28,%zmm29,%zmm30");
882 asm volatile("vaddpd %zmm28,%zmm29,%zmm30{%k7}");
883 asm volatile("vaddpd %zmm28,%zmm29,%zmm30{%k7}{z}");
884 asm volatile("vaddpd {rn-sae},%zmm28,%zmm29,%zmm30");
885 asm volatile("vaddpd {ru-sae},%zmm28,%zmm29,%zmm30");
886 asm volatile("vaddpd {rd-sae},%zmm28,%zmm29,%zmm30");
887 asm volatile("vaddpd {rz-sae},%zmm28,%zmm29,%zmm30");
888 asm volatile("vaddpd (%rcx),%zmm29,%zmm30");
889 asm volatile("vaddpd 0x123(%rax,%r14,8),%zmm29,%zmm30");
890 asm volatile("vaddpd (%rcx){1to8},%zmm29,%zmm30");
891 asm volatile("vaddpd 0x1fc0(%rdx),%zmm29,%zmm30");
892 asm volatile("vaddpd 0x3f8(%rdx){1to8},%zmm29,%zmm30");
893 asm volatile("vcmpeq_uqps 0x1fc(%rdx){1to16},%zmm30,%k5");
894 asm volatile("vcmpltsd 0x123(%rax,%r14,8),%xmm29,%k5{%k7}");
895 asm volatile("vcmplesd {sae},%xmm28,%xmm29,%k5{%k7}");
896 asm volatile("vgetmantss $0x5b,0x123(%rax,%r14,8),%xmm29,%xmm30{%k7}");
897
24 /* bndmk m64, bnd */ 898 /* bndmk m64, bnd */
25 899
26 asm volatile("bndmk (%rax), %bnd0"); 900 asm volatile("bndmk (%rax), %bnd0");
@@ -471,6 +1345,921 @@ int main(void)
471 1345
472#else /* #ifdef __x86_64__ */ 1346#else /* #ifdef __x86_64__ */
473 1347
1348 /* bound r32, mem (same op code as EVEX prefix) */
1349
1350 asm volatile("bound %eax, 0x12345678(%ecx)");
1351 asm volatile("bound %ecx, 0x12345678(%eax)");
1352 asm volatile("bound %edx, 0x12345678(%eax)");
1353 asm volatile("bound %ebx, 0x12345678(%eax)");
1354 asm volatile("bound %esp, 0x12345678(%eax)");
1355 asm volatile("bound %ebp, 0x12345678(%eax)");
1356 asm volatile("bound %esi, 0x12345678(%eax)");
1357 asm volatile("bound %edi, 0x12345678(%eax)");
1358 asm volatile("bound %ecx, (%eax)");
1359 asm volatile("bound %eax, (0x12345678)");
1360 asm volatile("bound %edx, (%ecx,%eax,1)");
1361 asm volatile("bound %edx, 0x12345678(,%eax,1)");
1362 asm volatile("bound %edx, (%eax,%ecx,1)");
1363 asm volatile("bound %edx, (%eax,%ecx,8)");
1364 asm volatile("bound %edx, 0x12(%eax)");
1365 asm volatile("bound %edx, 0x12(%ebp)");
1366 asm volatile("bound %edx, 0x12(%ecx,%eax,1)");
1367 asm volatile("bound %edx, 0x12(%ebp,%eax,1)");
1368 asm volatile("bound %edx, 0x12(%eax,%ecx,1)");
1369 asm volatile("bound %edx, 0x12(%eax,%ecx,8)");
1370 asm volatile("bound %edx, 0x12345678(%eax)");
1371 asm volatile("bound %edx, 0x12345678(%ebp)");
1372 asm volatile("bound %edx, 0x12345678(%ecx,%eax,1)");
1373 asm volatile("bound %edx, 0x12345678(%ebp,%eax,1)");
1374 asm volatile("bound %edx, 0x12345678(%eax,%ecx,1)");
1375 asm volatile("bound %edx, 0x12345678(%eax,%ecx,8)");
1376
1377 /* bound r16, mem (same op code as EVEX prefix) */
1378
1379 asm volatile("bound %ax, 0x12345678(%ecx)");
1380 asm volatile("bound %cx, 0x12345678(%eax)");
1381 asm volatile("bound %dx, 0x12345678(%eax)");
1382 asm volatile("bound %bx, 0x12345678(%eax)");
1383 asm volatile("bound %sp, 0x12345678(%eax)");
1384 asm volatile("bound %bp, 0x12345678(%eax)");
1385 asm volatile("bound %si, 0x12345678(%eax)");
1386 asm volatile("bound %di, 0x12345678(%eax)");
1387 asm volatile("bound %cx, (%eax)");
1388 asm volatile("bound %ax, (0x12345678)");
1389 asm volatile("bound %dx, (%ecx,%eax,1)");
1390 asm volatile("bound %dx, 0x12345678(,%eax,1)");
1391 asm volatile("bound %dx, (%eax,%ecx,1)");
1392 asm volatile("bound %dx, (%eax,%ecx,8)");
1393 asm volatile("bound %dx, 0x12(%eax)");
1394 asm volatile("bound %dx, 0x12(%ebp)");
1395 asm volatile("bound %dx, 0x12(%ecx,%eax,1)");
1396 asm volatile("bound %dx, 0x12(%ebp,%eax,1)");
1397 asm volatile("bound %dx, 0x12(%eax,%ecx,1)");
1398 asm volatile("bound %dx, 0x12(%eax,%ecx,8)");
1399 asm volatile("bound %dx, 0x12345678(%eax)");
1400 asm volatile("bound %dx, 0x12345678(%ebp)");
1401 asm volatile("bound %dx, 0x12345678(%ecx,%eax,1)");
1402 asm volatile("bound %dx, 0x12345678(%ebp,%eax,1)");
1403 asm volatile("bound %dx, 0x12345678(%eax,%ecx,1)");
1404 asm volatile("bound %dx, 0x12345678(%eax,%ecx,8)");
1405
1406 /* AVX-512: Instructions with the same op codes as Mask Instructions */
1407
1408 asm volatile("cmovno %eax,%ebx");
1409 asm volatile("cmovno 0x12345678(%eax),%ecx");
1410 asm volatile("cmovno 0x12345678(%eax),%cx");
1411
1412 asm volatile("cmove %eax,%ebx");
1413 asm volatile("cmove 0x12345678(%eax),%ecx");
1414 asm volatile("cmove 0x12345678(%eax),%cx");
1415
1416 asm volatile("seto 0x12345678(%eax)");
1417 asm volatile("setno 0x12345678(%eax)");
1418 asm volatile("setb 0x12345678(%eax)");
1419 asm volatile("setc 0x12345678(%eax)");
1420 asm volatile("setnae 0x12345678(%eax)");
1421 asm volatile("setae 0x12345678(%eax)");
1422 asm volatile("setnb 0x12345678(%eax)");
1423 asm volatile("setnc 0x12345678(%eax)");
1424 asm volatile("sets 0x12345678(%eax)");
1425 asm volatile("setns 0x12345678(%eax)");
1426
1427 /* AVX-512: Mask Instructions */
1428
1429 asm volatile("kandw %k7,%k6,%k5");
1430 asm volatile("kandq %k7,%k6,%k5");
1431 asm volatile("kandb %k7,%k6,%k5");
1432 asm volatile("kandd %k7,%k6,%k5");
1433
1434 asm volatile("kandnw %k7,%k6,%k5");
1435 asm volatile("kandnq %k7,%k6,%k5");
1436 asm volatile("kandnb %k7,%k6,%k5");
1437 asm volatile("kandnd %k7,%k6,%k5");
1438
1439 asm volatile("knotw %k7,%k6");
1440 asm volatile("knotq %k7,%k6");
1441 asm volatile("knotb %k7,%k6");
1442 asm volatile("knotd %k7,%k6");
1443
1444 asm volatile("korw %k7,%k6,%k5");
1445 asm volatile("korq %k7,%k6,%k5");
1446 asm volatile("korb %k7,%k6,%k5");
1447 asm volatile("kord %k7,%k6,%k5");
1448
1449 asm volatile("kxnorw %k7,%k6,%k5");
1450 asm volatile("kxnorq %k7,%k6,%k5");
1451 asm volatile("kxnorb %k7,%k6,%k5");
1452 asm volatile("kxnord %k7,%k6,%k5");
1453
1454 asm volatile("kxorw %k7,%k6,%k5");
1455 asm volatile("kxorq %k7,%k6,%k5");
1456 asm volatile("kxorb %k7,%k6,%k5");
1457 asm volatile("kxord %k7,%k6,%k5");
1458
1459 asm volatile("kaddw %k7,%k6,%k5");
1460 asm volatile("kaddq %k7,%k6,%k5");
1461 asm volatile("kaddb %k7,%k6,%k5");
1462 asm volatile("kaddd %k7,%k6,%k5");
1463
1464 asm volatile("kunpckbw %k7,%k6,%k5");
1465 asm volatile("kunpckwd %k7,%k6,%k5");
1466 asm volatile("kunpckdq %k7,%k6,%k5");
1467
1468 asm volatile("kmovw %k6,%k5");
1469 asm volatile("kmovw (%ecx),%k5");
1470 asm volatile("kmovw 0x123(%eax,%ecx,8),%k5");
1471 asm volatile("kmovw %k5,(%ecx)");
1472 asm volatile("kmovw %k5,0x123(%eax,%ecx,8)");
1473 asm volatile("kmovw %eax,%k5");
1474 asm volatile("kmovw %ebp,%k5");
1475 asm volatile("kmovw %k5,%eax");
1476 asm volatile("kmovw %k5,%ebp");
1477
1478 asm volatile("kmovq %k6,%k5");
1479 asm volatile("kmovq (%ecx),%k5");
1480 asm volatile("kmovq 0x123(%eax,%ecx,8),%k5");
1481 asm volatile("kmovq %k5,(%ecx)");
1482 asm volatile("kmovq %k5,0x123(%eax,%ecx,8)");
1483
1484 asm volatile("kmovb %k6,%k5");
1485 asm volatile("kmovb (%ecx),%k5");
1486 asm volatile("kmovb 0x123(%eax,%ecx,8),%k5");
1487 asm volatile("kmovb %k5,(%ecx)");
1488 asm volatile("kmovb %k5,0x123(%eax,%ecx,8)");
1489 asm volatile("kmovb %eax,%k5");
1490 asm volatile("kmovb %ebp,%k5");
1491 asm volatile("kmovb %k5,%eax");
1492 asm volatile("kmovb %k5,%ebp");
1493
1494 asm volatile("kmovd %k6,%k5");
1495 asm volatile("kmovd (%ecx),%k5");
1496 asm volatile("kmovd 0x123(%eax,%ecx,8),%k5");
1497 asm volatile("kmovd %k5,(%ecx)");
1498 asm volatile("kmovd %k5,0x123(%eax,%ecx,8)");
1499 asm volatile("kmovd %eax,%k5");
1500 asm volatile("kmovd %ebp,%k5");
1501 asm volatile("kmovd %k5,%eax");
1502 asm volatile("kmovd %k5,%ebp");
1503
1504 asm volatile("kortestw %k6,%k5");
1505 asm volatile("kortestq %k6,%k5");
1506 asm volatile("kortestb %k6,%k5");
1507 asm volatile("kortestd %k6,%k5");
1508
1509 asm volatile("ktestw %k6,%k5");
1510 asm volatile("ktestq %k6,%k5");
1511 asm volatile("ktestb %k6,%k5");
1512 asm volatile("ktestd %k6,%k5");
1513
1514 asm volatile("kshiftrw $0x12,%k6,%k5");
1515 asm volatile("kshiftrq $0x5b,%k6,%k5");
1516 asm volatile("kshiftlw $0x12,%k6,%k5");
1517 asm volatile("kshiftlq $0x5b,%k6,%k5");
1518
1519 /* AVX-512: Op code 0f 5b */
1520 asm volatile("vcvtdq2ps %xmm5,%xmm6");
1521 asm volatile("vcvtqq2ps %zmm5,%ymm6{%k7}");
1522 asm volatile("vcvtps2dq %xmm5,%xmm6");
1523 asm volatile("vcvttps2dq %xmm5,%xmm6");
1524
1525 /* AVX-512: Op code 0f 6f */
1526
1527 asm volatile("movq %mm0,%mm4");
1528 asm volatile("vmovdqa %ymm4,%ymm6");
1529 asm volatile("vmovdqa32 %zmm5,%zmm6");
1530 asm volatile("vmovdqa64 %zmm5,%zmm6");
1531 asm volatile("vmovdqu %ymm4,%ymm6");
1532 asm volatile("vmovdqu32 %zmm5,%zmm6");
1533 asm volatile("vmovdqu64 %zmm5,%zmm6");
1534 asm volatile("vmovdqu8 %zmm5,%zmm6");
1535 asm volatile("vmovdqu16 %zmm5,%zmm6");
1536
1537 /* AVX-512: Op code 0f 78 */
1538
1539 asm volatile("vmread %eax,%ebx");
1540 asm volatile("vcvttps2udq %zmm5,%zmm6");
1541 asm volatile("vcvttpd2udq %zmm5,%ymm6{%k7}");
1542 asm volatile("vcvttsd2usi %xmm6,%eax");
1543 asm volatile("vcvttss2usi %xmm6,%eax");
1544 asm volatile("vcvttps2uqq %ymm5,%zmm6{%k7}");
1545 asm volatile("vcvttpd2uqq %zmm5,%zmm6");
1546
1547 /* AVX-512: Op code 0f 79 */
1548
1549 asm volatile("vmwrite %eax,%ebx");
1550 asm volatile("vcvtps2udq %zmm5,%zmm6");
1551 asm volatile("vcvtpd2udq %zmm5,%ymm6{%k7}");
1552 asm volatile("vcvtsd2usi %xmm6,%eax");
1553 asm volatile("vcvtss2usi %xmm6,%eax");
1554 asm volatile("vcvtps2uqq %ymm5,%zmm6{%k7}");
1555 asm volatile("vcvtpd2uqq %zmm5,%zmm6");
1556
1557 /* AVX-512: Op code 0f 7a */
1558
1559 asm volatile("vcvtudq2pd %ymm5,%zmm6{%k7}");
1560 asm volatile("vcvtuqq2pd %zmm5,%zmm6");
1561 asm volatile("vcvtudq2ps %zmm5,%zmm6");
1562 asm volatile("vcvtuqq2ps %zmm5,%ymm6{%k7}");
1563 asm volatile("vcvttps2qq %ymm5,%zmm6{%k7}");
1564 asm volatile("vcvttpd2qq %zmm5,%zmm6");
1565
1566 /* AVX-512: Op code 0f 7b */
1567
1568 asm volatile("vcvtusi2sd %eax,%xmm5,%xmm6");
1569 asm volatile("vcvtusi2ss %eax,%xmm5,%xmm6");
1570 asm volatile("vcvtps2qq %ymm5,%zmm6{%k7}");
1571 asm volatile("vcvtpd2qq %zmm5,%zmm6");
1572
1573 /* AVX-512: Op code 0f 7f */
1574
1575 asm volatile("movq.s %mm0,%mm4");
1576 asm volatile("vmovdqa.s %ymm5,%ymm6");
1577 asm volatile("vmovdqa32.s %zmm5,%zmm6");
1578 asm volatile("vmovdqa64.s %zmm5,%zmm6");
1579 asm volatile("vmovdqu.s %ymm5,%ymm6");
1580 asm volatile("vmovdqu32.s %zmm5,%zmm6");
1581 asm volatile("vmovdqu64.s %zmm5,%zmm6");
1582 asm volatile("vmovdqu8.s %zmm5,%zmm6");
1583 asm volatile("vmovdqu16.s %zmm5,%zmm6");
1584
1585 /* AVX-512: Op code 0f db */
1586
1587 asm volatile("pand %mm1,%mm2");
1588 asm volatile("pand %xmm1,%xmm2");
1589 asm volatile("vpand %ymm4,%ymm6,%ymm2");
1590 asm volatile("vpandd %zmm4,%zmm5,%zmm6");
1591 asm volatile("vpandq %zmm4,%zmm5,%zmm6");
1592
1593 /* AVX-512: Op code 0f df */
1594
1595 asm volatile("pandn %mm1,%mm2");
1596 asm volatile("pandn %xmm1,%xmm2");
1597 asm volatile("vpandn %ymm4,%ymm6,%ymm2");
1598 asm volatile("vpandnd %zmm4,%zmm5,%zmm6");
1599 asm volatile("vpandnq %zmm4,%zmm5,%zmm6");
1600
1601 /* AVX-512: Op code 0f e6 */
1602
1603 asm volatile("vcvttpd2dq %xmm1,%xmm2");
1604 asm volatile("vcvtdq2pd %xmm5,%xmm6");
1605 asm volatile("vcvtdq2pd %ymm5,%zmm6{%k7}");
1606 asm volatile("vcvtqq2pd %zmm5,%zmm6");
1607 asm volatile("vcvtpd2dq %xmm1,%xmm2");
1608
1609 /* AVX-512: Op code 0f eb */
1610
1611 asm volatile("por %mm4,%mm6");
1612 asm volatile("vpor %ymm4,%ymm6,%ymm2");
1613 asm volatile("vpord %zmm4,%zmm5,%zmm6");
1614 asm volatile("vporq %zmm4,%zmm5,%zmm6");
1615
1616 /* AVX-512: Op code 0f ef */
1617
1618 asm volatile("pxor %mm4,%mm6");
1619 asm volatile("vpxor %ymm4,%ymm6,%ymm2");
1620 asm volatile("vpxord %zmm4,%zmm5,%zmm6");
1621 asm volatile("vpxorq %zmm4,%zmm5,%zmm6");
1622
1623 /* AVX-512: Op code 0f 38 10 */
1624
1625 asm volatile("pblendvb %xmm1,%xmm0");
1626 asm volatile("vpsrlvw %zmm4,%zmm5,%zmm6");
1627 asm volatile("vpmovuswb %zmm5,%ymm6{%k7}");
1628
1629 /* AVX-512: Op code 0f 38 11 */
1630
1631 asm volatile("vpmovusdb %zmm5,%xmm6{%k7}");
1632 asm volatile("vpsravw %zmm4,%zmm5,%zmm6");
1633
1634 /* AVX-512: Op code 0f 38 12 */
1635
1636 asm volatile("vpmovusqb %zmm5,%xmm6{%k7}");
1637 asm volatile("vpsllvw %zmm4,%zmm5,%zmm6");
1638
1639 /* AVX-512: Op code 0f 38 13 */
1640
1641 asm volatile("vcvtph2ps %xmm3,%ymm5");
1642 asm volatile("vcvtph2ps %ymm5,%zmm6{%k7}");
1643 asm volatile("vpmovusdw %zmm5,%ymm6{%k7}");
1644
1645 /* AVX-512: Op code 0f 38 14 */
1646
1647 asm volatile("blendvps %xmm1,%xmm0");
1648 asm volatile("vpmovusqw %zmm5,%xmm6{%k7}");
1649 asm volatile("vprorvd %zmm4,%zmm5,%zmm6");
1650 asm volatile("vprorvq %zmm4,%zmm5,%zmm6");
1651
1652 /* AVX-512: Op code 0f 38 15 */
1653
1654 asm volatile("blendvpd %xmm1,%xmm0");
1655 asm volatile("vpmovusqd %zmm5,%ymm6{%k7}");
1656 asm volatile("vprolvd %zmm4,%zmm5,%zmm6");
1657 asm volatile("vprolvq %zmm4,%zmm5,%zmm6");
1658
1659 /* AVX-512: Op code 0f 38 16 */
1660
1661 asm volatile("vpermps %ymm4,%ymm6,%ymm2");
1662 asm volatile("vpermps %ymm4,%ymm6,%ymm2{%k7}");
1663 asm volatile("vpermpd %ymm4,%ymm6,%ymm2{%k7}");
1664
1665 /* AVX-512: Op code 0f 38 19 */
1666
1667 asm volatile("vbroadcastsd %xmm4,%ymm6");
1668 asm volatile("vbroadcastf32x2 %xmm7,%zmm6");
1669
1670 /* AVX-512: Op code 0f 38 1a */
1671
1672 asm volatile("vbroadcastf128 (%ecx),%ymm4");
1673 asm volatile("vbroadcastf32x4 (%ecx),%zmm6");
1674 asm volatile("vbroadcastf64x2 (%ecx),%zmm6");
1675
1676 /* AVX-512: Op code 0f 38 1b */
1677
1678 asm volatile("vbroadcastf32x8 (%ecx),%zmm6");
1679 asm volatile("vbroadcastf64x4 (%ecx),%zmm6");
1680
1681 /* AVX-512: Op code 0f 38 1f */
1682
1683 asm volatile("vpabsq %zmm4,%zmm6");
1684
1685 /* AVX-512: Op code 0f 38 20 */
1686
1687 asm volatile("vpmovsxbw %xmm4,%xmm5");
1688 asm volatile("vpmovswb %zmm5,%ymm6{%k7}");
1689
1690 /* AVX-512: Op code 0f 38 21 */
1691
1692 asm volatile("vpmovsxbd %xmm4,%ymm6");
1693 asm volatile("vpmovsdb %zmm5,%xmm6{%k7}");
1694
1695 /* AVX-512: Op code 0f 38 22 */
1696
1697 asm volatile("vpmovsxbq %xmm4,%ymm4");
1698 asm volatile("vpmovsqb %zmm5,%xmm6{%k7}");
1699
1700 /* AVX-512: Op code 0f 38 23 */
1701
1702 asm volatile("vpmovsxwd %xmm4,%ymm4");
1703 asm volatile("vpmovsdw %zmm5,%ymm6{%k7}");
1704
1705 /* AVX-512: Op code 0f 38 24 */
1706
1707 asm volatile("vpmovsxwq %xmm4,%ymm6");
1708 asm volatile("vpmovsqw %zmm5,%xmm6{%k7}");
1709
1710 /* AVX-512: Op code 0f 38 25 */
1711
1712 asm volatile("vpmovsxdq %xmm4,%ymm4");
1713 asm volatile("vpmovsqd %zmm5,%ymm6{%k7}");
1714
1715 /* AVX-512: Op code 0f 38 26 */
1716
1717 asm volatile("vptestmb %zmm5,%zmm6,%k5");
1718 asm volatile("vptestmw %zmm5,%zmm6,%k5");
1719 asm volatile("vptestnmb %zmm4,%zmm5,%k5");
1720 asm volatile("vptestnmw %zmm4,%zmm5,%k5");
1721
1722 /* AVX-512: Op code 0f 38 27 */
1723
1724 asm volatile("vptestmd %zmm5,%zmm6,%k5");
1725 asm volatile("vptestmq %zmm5,%zmm6,%k5");
1726 asm volatile("vptestnmd %zmm4,%zmm5,%k5");
1727 asm volatile("vptestnmq %zmm4,%zmm5,%k5");
1728
1729 /* AVX-512: Op code 0f 38 28 */
1730
1731 asm volatile("vpmuldq %ymm4,%ymm6,%ymm2");
1732 asm volatile("vpmovm2b %k5,%zmm6");
1733 asm volatile("vpmovm2w %k5,%zmm6");
1734
1735 /* AVX-512: Op code 0f 38 29 */
1736
1737 asm volatile("vpcmpeqq %ymm4,%ymm6,%ymm2");
1738 asm volatile("vpmovb2m %zmm6,%k5");
1739 asm volatile("vpmovw2m %zmm6,%k5");
1740
1741 /* AVX-512: Op code 0f 38 2a */
1742
1743 asm volatile("vmovntdqa (%ecx),%ymm4");
1744 asm volatile("vpbroadcastmb2q %k6,%zmm1");
1745
1746 /* AVX-512: Op code 0f 38 2c */
1747
1748 asm volatile("vmaskmovps (%ecx),%ymm4,%ymm6");
1749 asm volatile("vscalefps %zmm4,%zmm5,%zmm6");
1750 asm volatile("vscalefpd %zmm4,%zmm5,%zmm6");
1751
1752 /* AVX-512: Op code 0f 38 2d */
1753
1754 asm volatile("vmaskmovpd (%ecx),%ymm4,%ymm6");
1755 asm volatile("vscalefss %xmm4,%xmm5,%xmm6{%k7}");
1756 asm volatile("vscalefsd %xmm4,%xmm5,%xmm6{%k7}");
1757
1758 /* AVX-512: Op code 0f 38 30 */
1759
1760 asm volatile("vpmovzxbw %xmm4,%ymm4");
1761 asm volatile("vpmovwb %zmm5,%ymm6{%k7}");
1762
1763 /* AVX-512: Op code 0f 38 31 */
1764
1765 asm volatile("vpmovzxbd %xmm4,%ymm6");
1766 asm volatile("vpmovdb %zmm5,%xmm6{%k7}");
1767
1768 /* AVX-512: Op code 0f 38 32 */
1769
1770 asm volatile("vpmovzxbq %xmm4,%ymm4");
1771 asm volatile("vpmovqb %zmm5,%xmm6{%k7}");
1772
1773 /* AVX-512: Op code 0f 38 33 */
1774
1775 asm volatile("vpmovzxwd %xmm4,%ymm4");
1776 asm volatile("vpmovdw %zmm5,%ymm6{%k7}");
1777
1778 /* AVX-512: Op code 0f 38 34 */
1779
1780 asm volatile("vpmovzxwq %xmm4,%ymm6");
1781 asm volatile("vpmovqw %zmm5,%xmm6{%k7}");
1782
1783 /* AVX-512: Op code 0f 38 35 */
1784
1785 asm volatile("vpmovzxdq %xmm4,%ymm4");
1786 asm volatile("vpmovqd %zmm5,%ymm6{%k7}");
1787
1788 /* AVX-512: Op code 0f 38 36 */
1789
1790 asm volatile("vpermd %ymm4,%ymm6,%ymm2");
1791 asm volatile("vpermd %ymm4,%ymm6,%ymm2{%k7}");
1792 asm volatile("vpermq %ymm4,%ymm6,%ymm2{%k7}");
1793
1794 /* AVX-512: Op code 0f 38 38 */
1795
1796 asm volatile("vpminsb %ymm4,%ymm6,%ymm2");
1797 asm volatile("vpmovm2d %k5,%zmm6");
1798 asm volatile("vpmovm2q %k5,%zmm6");
1799
1800 /* AVX-512: Op code 0f 38 39 */
1801
1802 asm volatile("vpminsd %xmm1,%xmm2,%xmm3");
1803 asm volatile("vpminsd %zmm4,%zmm5,%zmm6");
1804 asm volatile("vpminsq %zmm4,%zmm5,%zmm6");
1805 asm volatile("vpmovd2m %zmm6,%k5");
1806 asm volatile("vpmovq2m %zmm6,%k5");
1807
1808 /* AVX-512: Op code 0f 38 3a */
1809
1810 asm volatile("vpminuw %ymm4,%ymm6,%ymm2");
1811 asm volatile("vpbroadcastmw2d %k6,%zmm6");
1812
1813 /* AVX-512: Op code 0f 38 3b */
1814
1815 asm volatile("vpminud %ymm4,%ymm6,%ymm2");
1816 asm volatile("vpminud %zmm4,%zmm5,%zmm6");
1817 asm volatile("vpminuq %zmm4,%zmm5,%zmm6");
1818
1819 /* AVX-512: Op code 0f 38 3d */
1820
1821 asm volatile("vpmaxsd %ymm4,%ymm6,%ymm2");
1822 asm volatile("vpmaxsd %zmm4,%zmm5,%zmm6");
1823 asm volatile("vpmaxsq %zmm4,%zmm5,%zmm6");
1824
1825 /* AVX-512: Op code 0f 38 3f */
1826
1827 asm volatile("vpmaxud %ymm4,%ymm6,%ymm2");
1828 asm volatile("vpmaxud %zmm4,%zmm5,%zmm6");
1829 asm volatile("vpmaxuq %zmm4,%zmm5,%zmm6");
1830
1831 /* AVX-512: Op code 0f 38 40 */
1832
1833 asm volatile("vpmulld %ymm4,%ymm6,%ymm2");
1834 asm volatile("vpmulld %zmm4,%zmm5,%zmm6");
1835 asm volatile("vpmullq %zmm4,%zmm5,%zmm6");
1836
1837 /* AVX-512: Op code 0f 38 42 */
1838
1839 asm volatile("vgetexpps %zmm5,%zmm6");
1840 asm volatile("vgetexppd %zmm5,%zmm6");
1841
1842 /* AVX-512: Op code 0f 38 43 */
1843
1844 asm volatile("vgetexpss %xmm4,%xmm5,%xmm6{%k7}");
1845 asm volatile("vgetexpsd %xmm2,%xmm3,%xmm4{%k7}");
1846
1847 /* AVX-512: Op code 0f 38 44 */
1848
1849 asm volatile("vplzcntd %zmm5,%zmm6");
1850 asm volatile("vplzcntq %zmm5,%zmm6");
1851
1852 /* AVX-512: Op code 0f 38 46 */
1853
1854 asm volatile("vpsravd %ymm4,%ymm6,%ymm2");
1855 asm volatile("vpsravd %zmm4,%zmm5,%zmm6");
1856 asm volatile("vpsravq %zmm4,%zmm5,%zmm6");
1857
1858 /* AVX-512: Op code 0f 38 4c */
1859
1860 asm volatile("vrcp14ps %zmm5,%zmm6");
1861 asm volatile("vrcp14pd %zmm5,%zmm6");
1862
1863 /* AVX-512: Op code 0f 38 4d */
1864
1865 asm volatile("vrcp14ss %xmm4,%xmm5,%xmm6{%k7}");
1866 asm volatile("vrcp14sd %xmm4,%xmm5,%xmm6{%k7}");
1867
1868 /* AVX-512: Op code 0f 38 4e */
1869
1870 asm volatile("vrsqrt14ps %zmm5,%zmm6");
1871 asm volatile("vrsqrt14pd %zmm5,%zmm6");
1872
1873 /* AVX-512: Op code 0f 38 4f */
1874
1875 asm volatile("vrsqrt14ss %xmm4,%xmm5,%xmm6{%k7}");
1876 asm volatile("vrsqrt14sd %xmm4,%xmm5,%xmm6{%k7}");
1877
1878 /* AVX-512: Op code 0f 38 59 */
1879
1880 asm volatile("vpbroadcastq %xmm4,%xmm6");
1881 asm volatile("vbroadcasti32x2 %xmm7,%zmm6");
1882
1883 /* AVX-512: Op code 0f 38 5a */
1884
1885 asm volatile("vbroadcasti128 (%ecx),%ymm4");
1886 asm volatile("vbroadcasti32x4 (%ecx),%zmm6");
1887 asm volatile("vbroadcasti64x2 (%ecx),%zmm6");
1888
1889 /* AVX-512: Op code 0f 38 5b */
1890
1891 asm volatile("vbroadcasti32x8 (%ecx),%zmm6");
1892 asm volatile("vbroadcasti64x4 (%ecx),%zmm6");
1893
1894 /* AVX-512: Op code 0f 38 64 */
1895
1896 asm volatile("vpblendmd %zmm4,%zmm5,%zmm6");
1897 asm volatile("vpblendmq %zmm4,%zmm5,%zmm6");
1898
1899 /* AVX-512: Op code 0f 38 65 */
1900
1901 asm volatile("vblendmps %zmm4,%zmm5,%zmm6");
1902 asm volatile("vblendmpd %zmm4,%zmm5,%zmm6");
1903
1904 /* AVX-512: Op code 0f 38 66 */
1905
1906 asm volatile("vpblendmb %zmm4,%zmm5,%zmm6");
1907 asm volatile("vpblendmw %zmm4,%zmm5,%zmm6");
1908
1909 /* AVX-512: Op code 0f 38 75 */
1910
1911 asm volatile("vpermi2b %zmm4,%zmm5,%zmm6");
1912 asm volatile("vpermi2w %zmm4,%zmm5,%zmm6");
1913
1914 /* AVX-512: Op code 0f 38 76 */
1915
1916 asm volatile("vpermi2d %zmm4,%zmm5,%zmm6");
1917 asm volatile("vpermi2q %zmm4,%zmm5,%zmm6");
1918
1919 /* AVX-512: Op code 0f 38 77 */
1920
1921 asm volatile("vpermi2ps %zmm4,%zmm5,%zmm6");
1922 asm volatile("vpermi2pd %zmm4,%zmm5,%zmm6");
1923
1924 /* AVX-512: Op code 0f 38 7a */
1925
1926 asm volatile("vpbroadcastb %eax,%xmm3");
1927
1928 /* AVX-512: Op code 0f 38 7b */
1929
1930 asm volatile("vpbroadcastw %eax,%xmm3");
1931
1932 /* AVX-512: Op code 0f 38 7c */
1933
1934 asm volatile("vpbroadcastd %eax,%xmm3");
1935
1936 /* AVX-512: Op code 0f 38 7d */
1937
1938 asm volatile("vpermt2b %zmm4,%zmm5,%zmm6");
1939 asm volatile("vpermt2w %zmm4,%zmm5,%zmm6");
1940
1941 /* AVX-512: Op code 0f 38 7e */
1942
1943 asm volatile("vpermt2d %zmm4,%zmm5,%zmm6");
1944 asm volatile("vpermt2q %zmm4,%zmm5,%zmm6");
1945
1946 /* AVX-512: Op code 0f 38 7f */
1947
1948 asm volatile("vpermt2ps %zmm4,%zmm5,%zmm6");
1949 asm volatile("vpermt2pd %zmm4,%zmm5,%zmm6");
1950
1951 /* AVX-512: Op code 0f 38 83 */
1952
1953 asm volatile("vpmultishiftqb %zmm4,%zmm5,%zmm6");
1954
1955 /* AVX-512: Op code 0f 38 88 */
1956
1957 asm volatile("vexpandps (%ecx),%zmm6");
1958 asm volatile("vexpandpd (%ecx),%zmm6");
1959
1960 /* AVX-512: Op code 0f 38 89 */
1961
1962 asm volatile("vpexpandd (%ecx),%zmm6");
1963 asm volatile("vpexpandq (%ecx),%zmm6");
1964
1965 /* AVX-512: Op code 0f 38 8a */
1966
1967 asm volatile("vcompressps %zmm6,(%ecx)");
1968 asm volatile("vcompresspd %zmm6,(%ecx)");
1969
1970 /* AVX-512: Op code 0f 38 8b */
1971
1972 asm volatile("vpcompressd %zmm6,(%ecx)");
1973 asm volatile("vpcompressq %zmm6,(%ecx)");
1974
1975 /* AVX-512: Op code 0f 38 8d */
1976
1977 asm volatile("vpermb %zmm4,%zmm5,%zmm6");
1978 asm volatile("vpermw %zmm4,%zmm5,%zmm6");
1979
1980 /* AVX-512: Op code 0f 38 90 */
1981
1982 asm volatile("vpgatherdd %xmm2,0x02(%ebp,%xmm7,2),%xmm1");
1983 asm volatile("vpgatherdq %xmm2,0x04(%ebp,%xmm7,2),%xmm1");
1984 asm volatile("vpgatherdd 0x7b(%ebp,%zmm7,8),%zmm6{%k1}");
1985 asm volatile("vpgatherdq 0x7b(%ebp,%ymm7,8),%zmm6{%k1}");
1986
1987 /* AVX-512: Op code 0f 38 91 */
1988
1989 asm volatile("vpgatherqd %xmm2,0x02(%ebp,%xmm7,2),%xmm1");
1990 asm volatile("vpgatherqq %xmm2,0x02(%ebp,%xmm7,2),%xmm1");
1991 asm volatile("vpgatherqd 0x7b(%ebp,%zmm7,8),%ymm6{%k1}");
1992 asm volatile("vpgatherqq 0x7b(%ebp,%zmm7,8),%zmm6{%k1}");
1993
1994 /* AVX-512: Op code 0f 38 a0 */
1995
1996 asm volatile("vpscatterdd %zmm6,0x7b(%ebp,%zmm7,8){%k1}");
1997 asm volatile("vpscatterdq %zmm6,0x7b(%ebp,%ymm7,8){%k1}");
1998
1999 /* AVX-512: Op code 0f 38 a1 */
2000
2001 asm volatile("vpscatterqd %ymm6,0x7b(%ebp,%zmm7,8){%k1}");
2002 asm volatile("vpscatterqq %ymm6,0x7b(%ebp,%ymm7,8){%k1}");
2003
2004 /* AVX-512: Op code 0f 38 a2 */
2005
2006 asm volatile("vscatterdps %zmm6,0x7b(%ebp,%zmm7,8){%k1}");
2007 asm volatile("vscatterdpd %zmm6,0x7b(%ebp,%ymm7,8){%k1}");
2008
2009 /* AVX-512: Op code 0f 38 a3 */
2010
2011 asm volatile("vscatterqps %ymm6,0x7b(%ebp,%zmm7,8){%k1}");
2012 asm volatile("vscatterqpd %zmm6,0x7b(%ebp,%zmm7,8){%k1}");
2013
2014 /* AVX-512: Op code 0f 38 b4 */
2015
2016 asm volatile("vpmadd52luq %zmm4,%zmm5,%zmm6");
2017
2018 /* AVX-512: Op code 0f 38 b5 */
2019
2020 asm volatile("vpmadd52huq %zmm4,%zmm5,%zmm6");
2021
2022 /* AVX-512: Op code 0f 38 c4 */
2023
2024 asm volatile("vpconflictd %zmm5,%zmm6");
2025 asm volatile("vpconflictq %zmm5,%zmm6");
2026
2027 /* AVX-512: Op code 0f 38 c8 */
2028
2029 asm volatile("vexp2ps %zmm6,%zmm7");
2030 asm volatile("vexp2pd %zmm6,%zmm7");
2031
2032 /* AVX-512: Op code 0f 38 ca */
2033
2034 asm volatile("vrcp28ps %zmm6,%zmm7");
2035 asm volatile("vrcp28pd %zmm6,%zmm7");
2036
2037 /* AVX-512: Op code 0f 38 cb */
2038
2039 asm volatile("vrcp28ss %xmm5,%xmm6,%xmm7{%k7}");
2040 asm volatile("vrcp28sd %xmm5,%xmm6,%xmm7{%k7}");
2041
2042 /* AVX-512: Op code 0f 38 cc */
2043
2044 asm volatile("vrsqrt28ps %zmm6,%zmm7");
2045 asm volatile("vrsqrt28pd %zmm6,%zmm7");
2046
2047 /* AVX-512: Op code 0f 38 cd */
2048
2049 asm volatile("vrsqrt28ss %xmm5,%xmm6,%xmm7{%k7}");
2050 asm volatile("vrsqrt28sd %xmm5,%xmm6,%xmm7{%k7}");
2051
2052 /* AVX-512: Op code 0f 3a 03 */
2053
2054 asm volatile("valignd $0x12,%zmm5,%zmm6,%zmm7");
2055 asm volatile("valignq $0x12,%zmm5,%zmm6,%zmm7");
2056
2057 /* AVX-512: Op code 0f 3a 08 */
2058
2059 asm volatile("vroundps $0x5,%ymm6,%ymm2");
2060 asm volatile("vrndscaleps $0x12,%zmm5,%zmm6");
2061
2062 /* AVX-512: Op code 0f 3a 09 */
2063
2064 asm volatile("vroundpd $0x5,%ymm6,%ymm2");
2065 asm volatile("vrndscalepd $0x12,%zmm5,%zmm6");
2066
2067 /* AVX-512: Op code 0f 3a 0a */
2068
2069 asm volatile("vroundss $0x5,%xmm4,%xmm6,%xmm2");
2070 asm volatile("vrndscaless $0x12,%xmm4,%xmm5,%xmm6{%k7}");
2071
2072 /* AVX-512: Op code 0f 3a 0b */
2073
2074 asm volatile("vroundsd $0x5,%xmm4,%xmm6,%xmm2");
2075 asm volatile("vrndscalesd $0x12,%xmm4,%xmm5,%xmm6{%k7}");
2076
2077 /* AVX-512: Op code 0f 3a 18 */
2078
2079 asm volatile("vinsertf128 $0x5,%xmm4,%ymm4,%ymm6");
2080 asm volatile("vinsertf32x4 $0x12,%xmm4,%zmm5,%zmm6{%k7}");
2081 asm volatile("vinsertf64x2 $0x12,%xmm4,%zmm5,%zmm6{%k7}");
2082
2083 /* AVX-512: Op code 0f 3a 19 */
2084
2085 asm volatile("vextractf128 $0x5,%ymm4,%xmm4");
2086 asm volatile("vextractf32x4 $0x12,%zmm5,%xmm6{%k7}");
2087 asm volatile("vextractf64x2 $0x12,%zmm5,%xmm6{%k7}");
2088
2089 /* AVX-512: Op code 0f 3a 1a */
2090
2091 asm volatile("vinsertf32x8 $0x12,%ymm5,%zmm6,%zmm7{%k7}");
2092 asm volatile("vinsertf64x4 $0x12,%ymm5,%zmm6,%zmm7{%k7}");
2093
2094 /* AVX-512: Op code 0f 3a 1b */
2095
2096 asm volatile("vextractf32x8 $0x12,%zmm6,%ymm7{%k7}");
2097 asm volatile("vextractf64x4 $0x12,%zmm6,%ymm7{%k7}");
2098
2099 /* AVX-512: Op code 0f 3a 1e */
2100
2101 asm volatile("vpcmpud $0x12,%zmm6,%zmm7,%k5");
2102 asm volatile("vpcmpuq $0x12,%zmm6,%zmm7,%k5");
2103
2104 /* AVX-512: Op code 0f 3a 1f */
2105
2106 asm volatile("vpcmpd $0x12,%zmm6,%zmm7,%k5");
2107 asm volatile("vpcmpq $0x12,%zmm6,%zmm7,%k5");
2108
2109 /* AVX-512: Op code 0f 3a 23 */
2110
2111 asm volatile("vshuff32x4 $0x12,%zmm5,%zmm6,%zmm7");
2112 asm volatile("vshuff64x2 $0x12,%zmm5,%zmm6,%zmm7");
2113
2114 /* AVX-512: Op code 0f 3a 25 */
2115
2116 asm volatile("vpternlogd $0x12,%zmm5,%zmm6,%zmm7");
2117 asm volatile("vpternlogq $0x12,%zmm5,%zmm6,%zmm7");
2118
2119 /* AVX-512: Op code 0f 3a 26 */
2120
2121 asm volatile("vgetmantps $0x12,%zmm6,%zmm7");
2122 asm volatile("vgetmantpd $0x12,%zmm6,%zmm7");
2123
2124 /* AVX-512: Op code 0f 3a 27 */
2125
2126 asm volatile("vgetmantss $0x12,%xmm5,%xmm6,%xmm7{%k7}");
2127 asm volatile("vgetmantsd $0x12,%xmm5,%xmm6,%xmm7{%k7}");
2128
2129 /* AVX-512: Op code 0f 3a 38 */
2130
2131 asm volatile("vinserti128 $0x5,%xmm4,%ymm4,%ymm6");
2132 asm volatile("vinserti32x4 $0x12,%xmm4,%zmm5,%zmm6{%k7}");
2133 asm volatile("vinserti64x2 $0x12,%xmm4,%zmm5,%zmm6{%k7}");
2134
2135 /* AVX-512: Op code 0f 3a 39 */
2136
2137 asm volatile("vextracti128 $0x5,%ymm4,%xmm6");
2138 asm volatile("vextracti32x4 $0x12,%zmm5,%xmm6{%k7}");
2139 asm volatile("vextracti64x2 $0x12,%zmm5,%xmm6{%k7}");
2140
2141 /* AVX-512: Op code 0f 3a 3a */
2142
2143 asm volatile("vinserti32x8 $0x12,%ymm5,%zmm6,%zmm7{%k7}");
2144 asm volatile("vinserti64x4 $0x12,%ymm5,%zmm6,%zmm7{%k7}");
2145
2146 /* AVX-512: Op code 0f 3a 3b */
2147
2148 asm volatile("vextracti32x8 $0x12,%zmm6,%ymm7{%k7}");
2149 asm volatile("vextracti64x4 $0x12,%zmm6,%ymm7{%k7}");
2150
2151 /* AVX-512: Op code 0f 3a 3e */
2152
2153 asm volatile("vpcmpub $0x12,%zmm6,%zmm7,%k5");
2154 asm volatile("vpcmpuw $0x12,%zmm6,%zmm7,%k5");
2155
2156 /* AVX-512: Op code 0f 3a 3f */
2157
2158 asm volatile("vpcmpb $0x12,%zmm6,%zmm7,%k5");
2159 asm volatile("vpcmpw $0x12,%zmm6,%zmm7,%k5");
2160
2161 /* AVX-512: Op code 0f 3a 42 */
2162
2163 asm volatile("vmpsadbw $0x5,%ymm4,%ymm6,%ymm2");
2164 asm volatile("vdbpsadbw $0x12,%zmm4,%zmm5,%zmm6");
2165
2166 /* AVX-512: Op code 0f 3a 43 */
2167
2168 asm volatile("vshufi32x4 $0x12,%zmm5,%zmm6,%zmm7");
2169 asm volatile("vshufi64x2 $0x12,%zmm5,%zmm6,%zmm7");
2170
2171 /* AVX-512: Op code 0f 3a 50 */
2172
2173 asm volatile("vrangeps $0x12,%zmm5,%zmm6,%zmm7");
2174 asm volatile("vrangepd $0x12,%zmm5,%zmm6,%zmm7");
2175
2176 /* AVX-512: Op code 0f 3a 51 */
2177
2178 asm volatile("vrangess $0x12,%xmm5,%xmm6,%xmm7");
2179 asm volatile("vrangesd $0x12,%xmm5,%xmm6,%xmm7");
2180
2181 /* AVX-512: Op code 0f 3a 54 */
2182
2183 asm volatile("vfixupimmps $0x12,%zmm5,%zmm6,%zmm7");
2184 asm volatile("vfixupimmpd $0x12,%zmm5,%zmm6,%zmm7");
2185
2186 /* AVX-512: Op code 0f 3a 55 */
2187
2188 asm volatile("vfixupimmss $0x12,%xmm5,%xmm6,%xmm7{%k7}");
2189 asm volatile("vfixupimmsd $0x12,%xmm5,%xmm6,%xmm7{%k7}");
2190
2191 /* AVX-512: Op code 0f 3a 56 */
2192
2193 asm volatile("vreduceps $0x12,%zmm6,%zmm7");
2194 asm volatile("vreducepd $0x12,%zmm6,%zmm7");
2195
2196 /* AVX-512: Op code 0f 3a 57 */
2197
2198 asm volatile("vreducess $0x12,%xmm5,%xmm6,%xmm7");
2199 asm volatile("vreducesd $0x12,%xmm5,%xmm6,%xmm7");
2200
2201 /* AVX-512: Op code 0f 3a 66 */
2202
2203 asm volatile("vfpclassps $0x12,%zmm7,%k5");
2204 asm volatile("vfpclasspd $0x12,%zmm7,%k5");
2205
2206 /* AVX-512: Op code 0f 3a 67 */
2207
2208 asm volatile("vfpclassss $0x12,%xmm7,%k5");
2209 asm volatile("vfpclasssd $0x12,%xmm7,%k5");
2210
2211 /* AVX-512: Op code 0f 72 (Grp13) */
2212
2213 asm volatile("vprord $0x12,%zmm5,%zmm6");
2214 asm volatile("vprorq $0x12,%zmm5,%zmm6");
2215 asm volatile("vprold $0x12,%zmm5,%zmm6");
2216 asm volatile("vprolq $0x12,%zmm5,%zmm6");
2217 asm volatile("psrad $0x2,%mm6");
2218 asm volatile("vpsrad $0x5,%ymm6,%ymm2");
2219 asm volatile("vpsrad $0x5,%zmm6,%zmm2");
2220 asm volatile("vpsraq $0x5,%zmm6,%zmm2");
2221
2222 /* AVX-512: Op code 0f 38 c6 (Grp18) */
2223
2224 asm volatile("vgatherpf0dps 0x7b(%ebp,%zmm7,8){%k1}");
2225 asm volatile("vgatherpf0dpd 0x7b(%ebp,%ymm7,8){%k1}");
2226 asm volatile("vgatherpf1dps 0x7b(%ebp,%zmm7,8){%k1}");
2227 asm volatile("vgatherpf1dpd 0x7b(%ebp,%ymm7,8){%k1}");
2228 asm volatile("vscatterpf0dps 0x7b(%ebp,%zmm7,8){%k1}");
2229 asm volatile("vscatterpf0dpd 0x7b(%ebp,%ymm7,8){%k1}");
2230 asm volatile("vscatterpf1dps 0x7b(%ebp,%zmm7,8){%k1}");
2231 asm volatile("vscatterpf1dpd 0x7b(%ebp,%ymm7,8){%k1}");
2232
2233 /* AVX-512: Op code 0f 38 c7 (Grp19) */
2234
2235 asm volatile("vgatherpf0qps 0x7b(%ebp,%zmm7,8){%k1}");
2236 asm volatile("vgatherpf0qpd 0x7b(%ebp,%zmm7,8){%k1}");
2237 asm volatile("vgatherpf1qps 0x7b(%ebp,%zmm7,8){%k1}");
2238 asm volatile("vgatherpf1qpd 0x7b(%ebp,%zmm7,8){%k1}");
2239 asm volatile("vscatterpf0qps 0x7b(%ebp,%zmm7,8){%k1}");
2240 asm volatile("vscatterpf0qpd 0x7b(%ebp,%zmm7,8){%k1}");
2241 asm volatile("vscatterpf1qps 0x7b(%ebp,%zmm7,8){%k1}");
2242 asm volatile("vscatterpf1qpd 0x7b(%ebp,%zmm7,8){%k1}");
2243
2244 /* AVX-512: Examples */
2245
2246 asm volatile("vaddpd %zmm4,%zmm5,%zmm6");
2247 asm volatile("vaddpd %zmm4,%zmm5,%zmm6{%k7}");
2248 asm volatile("vaddpd %zmm4,%zmm5,%zmm6{%k7}{z}");
2249 asm volatile("vaddpd {rn-sae},%zmm4,%zmm5,%zmm6");
2250 asm volatile("vaddpd {ru-sae},%zmm4,%zmm5,%zmm6");
2251 asm volatile("vaddpd {rd-sae},%zmm4,%zmm5,%zmm6");
2252 asm volatile("vaddpd {rz-sae},%zmm4,%zmm5,%zmm6");
2253 asm volatile("vaddpd (%ecx),%zmm5,%zmm6");
2254 asm volatile("vaddpd 0x123(%eax,%ecx,8),%zmm5,%zmm6");
2255 asm volatile("vaddpd (%ecx){1to8},%zmm5,%zmm6");
2256 asm volatile("vaddpd 0x1fc0(%edx),%zmm5,%zmm6");
2257 asm volatile("vaddpd 0x3f8(%edx){1to8},%zmm5,%zmm6");
2258 asm volatile("vcmpeq_uqps 0x1fc(%edx){1to16},%zmm6,%k5");
2259 asm volatile("vcmpltsd 0x123(%eax,%ecx,8),%xmm3,%k5{%k7}");
2260 asm volatile("vcmplesd {sae},%xmm4,%xmm5,%k5{%k7}");
2261 asm volatile("vgetmantss $0x5b,0x123(%eax,%ecx,8),%xmm4,%xmm5{%k7}");
2262
474 /* bndmk m32, bnd */ 2263 /* bndmk m32, bnd */
475 2264
476 asm volatile("bndmk (%eax), %bnd0"); 2265 asm volatile("bndmk (%eax), %bnd0");
@@ -866,10 +2655,6 @@ int main(void)
866 2655
867#endif /* #ifndef __x86_64__ */ 2656#endif /* #ifndef __x86_64__ */
868 2657
869 /* pcommit */
870
871 asm volatile("pcommit");
872
873 /* Following line is a marker for the awk script - do not change */ 2658 /* Following line is a marker for the awk script - do not change */
874 asm volatile("rdtsc"); /* Stop here */ 2659 asm volatile("rdtsc"); /* Stop here */
875 2660
diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
index d4aa567a29c4..5c76cc83186a 100644
--- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c
+++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
@@ -154,10 +154,6 @@ next_event:
154 err = 0; 154 err = 0;
155 155
156out_err: 156out_err:
157 if (evlist) { 157 perf_evlist__delete(evlist);
158 perf_evlist__disable(evlist);
159 perf_evlist__delete(evlist);
160 }
161
162 return err; 158 return err;
163} 159}
diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c
index 72193f19d6d7..500cf96db979 100644
--- a/tools/perf/arch/x86/tests/rdpmc.c
+++ b/tools/perf/arch/x86/tests/rdpmc.c
@@ -1,12 +1,16 @@
1#include <errno.h>
1#include <unistd.h> 2#include <unistd.h>
2#include <stdlib.h> 3#include <stdlib.h>
3#include <signal.h> 4#include <signal.h>
4#include <sys/mman.h> 5#include <sys/mman.h>
6#include <sys/types.h>
7#include <sys/wait.h>
5#include <linux/types.h> 8#include <linux/types.h>
6#include "perf.h" 9#include "perf.h"
7#include "debug.h" 10#include "debug.h"
8#include "tests/tests.h" 11#include "tests/tests.h"
9#include "cloexec.h" 12#include "cloexec.h"
13#include "util.h"
10#include "arch-tests.h" 14#include "arch-tests.h"
11 15
12static u64 rdpmc(unsigned int counter) 16static u64 rdpmc(unsigned int counter)
@@ -111,14 +115,14 @@ static int __test__rdpmc(void)
111 if (fd < 0) { 115 if (fd < 0) {
112 pr_err("Error: sys_perf_event_open() syscall returned " 116 pr_err("Error: sys_perf_event_open() syscall returned "
113 "with %d (%s)\n", fd, 117 "with %d (%s)\n", fd,
114 strerror_r(errno, sbuf, sizeof(sbuf))); 118 str_error_r(errno, sbuf, sizeof(sbuf)));
115 return -1; 119 return -1;
116 } 120 }
117 121
118 addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); 122 addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
119 if (addr == (void *)(-1)) { 123 if (addr == (void *)(-1)) {
120 pr_err("Error: mmap() syscall returned with (%s)\n", 124 pr_err("Error: mmap() syscall returned with (%s)\n",
121 strerror_r(errno, sbuf, sizeof(sbuf))); 125 str_error_r(errno, sbuf, sizeof(sbuf)));
122 goto out_close; 126 goto out_close;
123 } 127 }
124 128
diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index 465970370f3e..f95e6f46ef0d 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -3,11 +3,12 @@ libperf-y += tsc.o
3libperf-y += pmu.o 3libperf-y += pmu.o
4libperf-y += kvm-stat.o 4libperf-y += kvm-stat.o
5libperf-y += perf_regs.o 5libperf-y += perf_regs.o
6libperf-y += group.o
6 7
7libperf-$(CONFIG_DWARF) += dwarf-regs.o 8libperf-$(CONFIG_DWARF) += dwarf-regs.o
8libperf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o 9libperf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
9 10
10libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o 11libperf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
11libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o 12libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
12 13
13libperf-$(CONFIG_AUXTRACE) += auxtrace.o 14libperf-$(CONFIG_AUXTRACE) += auxtrace.o
diff --git a/tools/perf/arch/x86/util/auxtrace.c b/tools/perf/arch/x86/util/auxtrace.c
index 7a7805583e3f..cc1d865e31f1 100644
--- a/tools/perf/arch/x86/util/auxtrace.c
+++ b/tools/perf/arch/x86/util/auxtrace.c
@@ -37,7 +37,7 @@ struct auxtrace_record *auxtrace_record__init_intel(struct perf_evlist *evlist,
37 intel_bts_pmu = perf_pmu__find(INTEL_BTS_PMU_NAME); 37 intel_bts_pmu = perf_pmu__find(INTEL_BTS_PMU_NAME);
38 38
39 if (evlist) { 39 if (evlist) {
40 evlist__for_each(evlist, evsel) { 40 evlist__for_each_entry(evlist, evsel) {
41 if (intel_pt_pmu && 41 if (intel_pt_pmu &&
42 evsel->attr.type == intel_pt_pmu->type) 42 evsel->attr.type == intel_pt_pmu->type)
43 found_pt = true; 43 found_pt = true;
diff --git a/tools/perf/arch/x86/util/group.c b/tools/perf/arch/x86/util/group.c
new file mode 100644
index 000000000000..37f92aa39a5d
--- /dev/null
+++ b/tools/perf/arch/x86/util/group.c
@@ -0,0 +1,27 @@
1#include <stdio.h>
2#include "api/fs/fs.h"
3#include "util/group.h"
4
5/*
6 * Check whether we can use a group for top down.
7 * Without a group may get bad results due to multiplexing.
8 */
9bool arch_topdown_check_group(bool *warn)
10{
11 int n;
12
13 if (sysctl__read_int("kernel/nmi_watchdog", &n) < 0)
14 return false;
15 if (n > 0) {
16 *warn = true;
17 return false;
18 }
19 return true;
20}
21
22void arch_topdown_group_warn(void)
23{
24 fprintf(stderr,
25 "nmi_watchdog enabled with topdown. May give wrong results.\n"
26 "Disable with echo 0 > /proc/sys/kernel/nmi_watchdog\n");
27}
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c
index 7dc30637cf66..5132775a044f 100644
--- a/tools/perf/arch/x86/util/intel-bts.c
+++ b/tools/perf/arch/x86/util/intel-bts.c
@@ -124,7 +124,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr,
124 btsr->evlist = evlist; 124 btsr->evlist = evlist;
125 btsr->snapshot_mode = opts->auxtrace_snapshot_mode; 125 btsr->snapshot_mode = opts->auxtrace_snapshot_mode;
126 126
127 evlist__for_each(evlist, evsel) { 127 evlist__for_each_entry(evlist, evsel) {
128 if (evsel->attr.type == intel_bts_pmu->type) { 128 if (evsel->attr.type == intel_bts_pmu->type) {
129 if (intel_bts_evsel) { 129 if (intel_bts_evsel) {
130 pr_err("There may be only one " INTEL_BTS_PMU_NAME " event\n"); 130 pr_err("There may be only one " INTEL_BTS_PMU_NAME " event\n");
@@ -327,7 +327,7 @@ static int intel_bts_snapshot_start(struct auxtrace_record *itr)
327 container_of(itr, struct intel_bts_recording, itr); 327 container_of(itr, struct intel_bts_recording, itr);
328 struct perf_evsel *evsel; 328 struct perf_evsel *evsel;
329 329
330 evlist__for_each(btsr->evlist, evsel) { 330 evlist__for_each_entry(btsr->evlist, evsel) {
331 if (evsel->attr.type == btsr->intel_bts_pmu->type) 331 if (evsel->attr.type == btsr->intel_bts_pmu->type)
332 return perf_evsel__disable(evsel); 332 return perf_evsel__disable(evsel);
333 } 333 }
@@ -340,7 +340,7 @@ static int intel_bts_snapshot_finish(struct auxtrace_record *itr)
340 container_of(itr, struct intel_bts_recording, itr); 340 container_of(itr, struct intel_bts_recording, itr);
341 struct perf_evsel *evsel; 341 struct perf_evsel *evsel;
342 342
343 evlist__for_each(btsr->evlist, evsel) { 343 evlist__for_each_entry(btsr->evlist, evsel) {
344 if (evsel->attr.type == btsr->intel_bts_pmu->type) 344 if (evsel->attr.type == btsr->intel_bts_pmu->type)
345 return perf_evsel__enable(evsel); 345 return perf_evsel__enable(evsel);
346 } 346 }
@@ -422,7 +422,7 @@ static int intel_bts_read_finish(struct auxtrace_record *itr, int idx)
422 container_of(itr, struct intel_bts_recording, itr); 422 container_of(itr, struct intel_bts_recording, itr);
423 struct perf_evsel *evsel; 423 struct perf_evsel *evsel;
424 424
425 evlist__for_each(btsr->evlist, evsel) { 425 evlist__for_each_entry(btsr->evlist, evsel) {
426 if (evsel->attr.type == btsr->intel_bts_pmu->type) 426 if (evsel->attr.type == btsr->intel_bts_pmu->type)
427 return perf_evlist__enable_event_idx(btsr->evlist, 427 return perf_evlist__enable_event_idx(btsr->evlist,
428 evsel, idx); 428 evsel, idx);
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index a07b9605e93b..fb51457ba338 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -131,7 +131,7 @@ static int intel_pt_read_config(struct perf_pmu *intel_pt_pmu, const char *str,
131 if (!mask) 131 if (!mask)
132 return -EINVAL; 132 return -EINVAL;
133 133
134 evlist__for_each(evlist, evsel) { 134 evlist__for_each_entry(evlist, evsel) {
135 if (evsel->attr.type == intel_pt_pmu->type) { 135 if (evsel->attr.type == intel_pt_pmu->type) {
136 *res = intel_pt_masked_bits(mask, evsel->attr.config); 136 *res = intel_pt_masked_bits(mask, evsel->attr.config);
137 return 0; 137 return 0;
@@ -511,7 +511,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
511 ptr->evlist = evlist; 511 ptr->evlist = evlist;
512 ptr->snapshot_mode = opts->auxtrace_snapshot_mode; 512 ptr->snapshot_mode = opts->auxtrace_snapshot_mode;
513 513
514 evlist__for_each(evlist, evsel) { 514 evlist__for_each_entry(evlist, evsel) {
515 if (evsel->attr.type == intel_pt_pmu->type) { 515 if (evsel->attr.type == intel_pt_pmu->type) {
516 if (intel_pt_evsel) { 516 if (intel_pt_evsel) {
517 pr_err("There may be only one " INTEL_PT_PMU_NAME " event\n"); 517 pr_err("There may be only one " INTEL_PT_PMU_NAME " event\n");
@@ -725,7 +725,7 @@ static int intel_pt_snapshot_start(struct auxtrace_record *itr)
725 container_of(itr, struct intel_pt_recording, itr); 725 container_of(itr, struct intel_pt_recording, itr);
726 struct perf_evsel *evsel; 726 struct perf_evsel *evsel;
727 727
728 evlist__for_each(ptr->evlist, evsel) { 728 evlist__for_each_entry(ptr->evlist, evsel) {
729 if (evsel->attr.type == ptr->intel_pt_pmu->type) 729 if (evsel->attr.type == ptr->intel_pt_pmu->type)
730 return perf_evsel__disable(evsel); 730 return perf_evsel__disable(evsel);
731 } 731 }
@@ -738,7 +738,7 @@ static int intel_pt_snapshot_finish(struct auxtrace_record *itr)
738 container_of(itr, struct intel_pt_recording, itr); 738 container_of(itr, struct intel_pt_recording, itr);
739 struct perf_evsel *evsel; 739 struct perf_evsel *evsel;
740 740
741 evlist__for_each(ptr->evlist, evsel) { 741 evlist__for_each_entry(ptr->evlist, evsel) {
742 if (evsel->attr.type == ptr->intel_pt_pmu->type) 742 if (evsel->attr.type == ptr->intel_pt_pmu->type)
743 return perf_evsel__enable(evsel); 743 return perf_evsel__enable(evsel);
744 } 744 }
@@ -1011,7 +1011,7 @@ static int intel_pt_read_finish(struct auxtrace_record *itr, int idx)
1011 container_of(itr, struct intel_pt_recording, itr); 1011 container_of(itr, struct intel_pt_recording, itr);
1012 struct perf_evsel *evsel; 1012 struct perf_evsel *evsel;
1013 1013
1014 evlist__for_each(ptr->evlist, evsel) { 1014 evlist__for_each_entry(ptr->evlist, evsel) {
1015 if (evsel->attr.type == ptr->intel_pt_pmu->type) 1015 if (evsel->attr.type == ptr->intel_pt_pmu->type)
1016 return perf_evlist__enable_event_idx(ptr->evlist, evsel, 1016 return perf_evlist__enable_event_idx(ptr->evlist, evsel,
1017 idx); 1017 idx);
diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c
index 357f1b13b5ae..2e5567c94e09 100644
--- a/tools/perf/arch/x86/util/tsc.c
+++ b/tools/perf/arch/x86/util/tsc.c
@@ -62,6 +62,8 @@ int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc,
62 struct perf_tsc_conversion tc; 62 struct perf_tsc_conversion tc;
63 int err; 63 int err;
64 64
65 if (!pc)
66 return 0;
65 err = perf_read_tsc_conversion(pc, &tc); 67 err = perf_read_tsc_conversion(pc, &tc);
66 if (err == -EOPNOTSUPP) 68 if (err == -EOPNOTSUPP)
67 return 0; 69 return 0;
diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c
index db25e93d989c..4f16661cbdbb 100644
--- a/tools/perf/arch/x86/util/unwind-libunwind.c
+++ b/tools/perf/arch/x86/util/unwind-libunwind.c
@@ -1,12 +1,14 @@
1 1
2#ifndef REMOTE_UNWIND_LIBUNWIND
2#include <errno.h> 3#include <errno.h>
3#include <libunwind.h> 4#include <libunwind.h>
4#include "perf_regs.h" 5#include "perf_regs.h"
5#include "../../util/unwind.h" 6#include "../../util/unwind.h"
6#include "../../util/debug.h" 7#include "../../util/debug.h"
8#endif
7 9
8#ifdef HAVE_ARCH_X86_64_SUPPORT 10#ifdef HAVE_ARCH_X86_64_SUPPORT
9int libunwind__arch_reg_id(int regnum) 11int LIBUNWIND__ARCH_REG_ID(int regnum)
10{ 12{
11 int id; 13 int id;
12 14
@@ -70,7 +72,7 @@ int libunwind__arch_reg_id(int regnum)
70 return id; 72 return id;
71} 73}
72#else 74#else
73int libunwind__arch_reg_id(int regnum) 75int LIBUNWIND__ARCH_REG_ID(int regnum)
74{ 76{
75 int id; 77 int id;
76 78
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
index 0999ac536d86..8024cd5febd2 100644
--- a/tools/perf/bench/futex-hash.c
+++ b/tools/perf/bench/futex-hash.c
@@ -8,18 +8,23 @@
8 * many threads and futexes as possible. 8 * many threads and futexes as possible.
9 */ 9 */
10 10
11#include "../perf.h" 11/* For the CLR_() macros */
12#include "../util/util.h" 12#include <pthread.h>
13
14#include <errno.h>
15#include <signal.h>
16#include <stdlib.h>
17#include <linux/compiler.h>
18#include <linux/kernel.h>
19#include <sys/time.h>
20
13#include "../util/stat.h" 21#include "../util/stat.h"
14#include <subcmd/parse-options.h> 22#include <subcmd/parse-options.h>
15#include "../util/header.h"
16#include "bench.h" 23#include "bench.h"
17#include "futex.h" 24#include "futex.h"
18 25
19#include <err.h> 26#include <err.h>
20#include <stdlib.h>
21#include <sys/time.h> 27#include <sys/time.h>
22#include <pthread.h>
23 28
24static unsigned int nthreads = 0; 29static unsigned int nthreads = 0;
25static unsigned int nsecs = 10; 30static unsigned int nsecs = 10;
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
index 6952db65508a..936d89d30483 100644
--- a/tools/perf/bench/futex-lock-pi.c
+++ b/tools/perf/bench/futex-lock-pi.c
@@ -2,18 +2,21 @@
2 * Copyright (C) 2015 Davidlohr Bueso. 2 * Copyright (C) 2015 Davidlohr Bueso.
3 */ 3 */
4 4
5#include "../perf.h" 5/* For the CLR_() macros */
6#include "../util/util.h" 6#include <pthread.h>
7
8#include <signal.h>
7#include "../util/stat.h" 9#include "../util/stat.h"
8#include <subcmd/parse-options.h> 10#include <subcmd/parse-options.h>
9#include "../util/header.h" 11#include <linux/compiler.h>
12#include <linux/kernel.h>
13#include <errno.h>
10#include "bench.h" 14#include "bench.h"
11#include "futex.h" 15#include "futex.h"
12 16
13#include <err.h> 17#include <err.h>
14#include <stdlib.h> 18#include <stdlib.h>
15#include <sys/time.h> 19#include <sys/time.h>
16#include <pthread.h>
17 20
18struct worker { 21struct worker {
19 int tid; 22 int tid;
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c
index 718238683013..f96e22ed9f87 100644
--- a/tools/perf/bench/futex-requeue.c
+++ b/tools/perf/bench/futex-requeue.c
@@ -8,18 +8,21 @@
8 * requeues without waking up any tasks -- thus mimicking a regular futex_wait. 8 * requeues without waking up any tasks -- thus mimicking a regular futex_wait.
9 */ 9 */
10 10
11#include "../perf.h" 11/* For the CLR_() macros */
12#include "../util/util.h" 12#include <pthread.h>
13
14#include <signal.h>
13#include "../util/stat.h" 15#include "../util/stat.h"
14#include <subcmd/parse-options.h> 16#include <subcmd/parse-options.h>
15#include "../util/header.h" 17#include <linux/compiler.h>
18#include <linux/kernel.h>
19#include <errno.h>
16#include "bench.h" 20#include "bench.h"
17#include "futex.h" 21#include "futex.h"
18 22
19#include <err.h> 23#include <err.h>
20#include <stdlib.h> 24#include <stdlib.h>
21#include <sys/time.h> 25#include <sys/time.h>
22#include <pthread.h>
23 26
24static u_int32_t futex1 = 0, futex2 = 0; 27static u_int32_t futex1 = 0, futex2 = 0;
25 28
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c
index 91aaf2a1fa90..4a2ecd7438ca 100644
--- a/tools/perf/bench/futex-wake-parallel.c
+++ b/tools/perf/bench/futex-wake-parallel.c
@@ -7,18 +7,21 @@
7 * it can be used to measure futex_wake() changes. 7 * it can be used to measure futex_wake() changes.
8 */ 8 */
9 9
10#include "../perf.h" 10/* For the CLR_() macros */
11#include "../util/util.h" 11#include <pthread.h>
12
13#include <signal.h>
12#include "../util/stat.h" 14#include "../util/stat.h"
13#include <subcmd/parse-options.h> 15#include <subcmd/parse-options.h>
14#include "../util/header.h" 16#include <linux/compiler.h>
17#include <linux/kernel.h>
18#include <errno.h>
15#include "bench.h" 19#include "bench.h"
16#include "futex.h" 20#include "futex.h"
17 21
18#include <err.h> 22#include <err.h>
19#include <stdlib.h> 23#include <stdlib.h>
20#include <sys/time.h> 24#include <sys/time.h>
21#include <pthread.h>
22 25
23struct thread_data { 26struct thread_data {
24 pthread_t worker; 27 pthread_t worker;
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c
index f416bd705f66..87d8f4f292d9 100644
--- a/tools/perf/bench/futex-wake.c
+++ b/tools/perf/bench/futex-wake.c
@@ -8,18 +8,21 @@
8 * one or more tasks, and thus the waitqueue is never empty. 8 * one or more tasks, and thus the waitqueue is never empty.
9 */ 9 */
10 10
11#include "../perf.h" 11/* For the CLR_() macros */
12#include "../util/util.h" 12#include <pthread.h>
13
14#include <signal.h>
13#include "../util/stat.h" 15#include "../util/stat.h"
14#include <subcmd/parse-options.h> 16#include <subcmd/parse-options.h>
15#include "../util/header.h" 17#include <linux/compiler.h>
18#include <linux/kernel.h>
19#include <errno.h>
16#include "bench.h" 20#include "bench.h"
17#include "futex.h" 21#include "futex.h"
18 22
19#include <err.h> 23#include <err.h>
20#include <stdlib.h> 24#include <stdlib.h>
21#include <sys/time.h> 25#include <sys/time.h>
22#include <pthread.h>
23 26
24/* all threads will block on the same futex */ 27/* all threads will block on the same futex */
25static u_int32_t futex1 = 0; 28static u_int32_t futex1 = 0;
diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm.S b/tools/perf/bench/mem-memcpy-x86-64-asm.S
index 5c3cce082cb8..f700369bb0f6 100644
--- a/tools/perf/bench/mem-memcpy-x86-64-asm.S
+++ b/tools/perf/bench/mem-memcpy-x86-64-asm.S
@@ -6,7 +6,7 @@
6#define globl p2align 4; .globl 6#define globl p2align 4; .globl
7#define _ASM_EXTABLE_FAULT(x, y) 7#define _ASM_EXTABLE_FAULT(x, y)
8 8
9#include "../../../arch/x86/lib/memcpy_64.S" 9#include "../../arch/x86/lib/memcpy_64.S"
10/* 10/*
11 * We need to provide note.GNU-stack section, saying that we want 11 * We need to provide note.GNU-stack section, saying that we want
12 * NOT executable stack. Otherwise the final linking will assume that 12 * NOT executable stack. Otherwise the final linking will assume that
diff --git a/tools/perf/bench/mem-memset-x86-64-asm.S b/tools/perf/bench/mem-memset-x86-64-asm.S
index de278784c866..58407aa24c1b 100644
--- a/tools/perf/bench/mem-memset-x86-64-asm.S
+++ b/tools/perf/bench/mem-memset-x86-64-asm.S
@@ -1,7 +1,7 @@
1#define memset MEMSET /* don't hide glibc's memset() */ 1#define memset MEMSET /* don't hide glibc's memset() */
2#define altinstr_replacement text 2#define altinstr_replacement text
3#define globl p2align 4; .globl 3#define globl p2align 4; .globl
4#include "../../../arch/x86/lib/memset_64.S" 4#include "../../arch/x86/lib/memset_64.S"
5 5
6/* 6/*
7 * We need to provide note.GNU-stack section, saying that we want 7 * We need to provide note.GNU-stack section, saying that we want
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 7500d959d7eb..f7f530081aa9 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -4,6 +4,9 @@
4 * numa: Simulate NUMA-sensitive workload and measure their NUMA performance 4 * numa: Simulate NUMA-sensitive workload and measure their NUMA performance
5 */ 5 */
6 6
7/* For the CLR_() macros */
8#include <pthread.h>
9
7#include "../perf.h" 10#include "../perf.h"
8#include "../builtin.h" 11#include "../builtin.h"
9#include "../util/util.h" 12#include "../util/util.h"
@@ -21,7 +24,6 @@
21#include <stdlib.h> 24#include <stdlib.h>
22#include <string.h> 25#include <string.h>
23#include <unistd.h> 26#include <unistd.h>
24#include <pthread.h>
25#include <sys/mman.h> 27#include <sys/mman.h>
26#include <sys/time.h> 28#include <sys/time.h>
27#include <sys/resource.h> 29#include <sys/resource.h>
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 25c81734a950..9c1034d81b4f 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -75,7 +75,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
75 sample->period = 1; 75 sample->period = 1;
76 sample->weight = 1; 76 sample->weight = 1;
77 77
78 he = __hists__add_entry(hists, al, NULL, NULL, NULL, sample, true); 78 he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true);
79 if (he == NULL) 79 if (he == NULL)
80 return -ENOMEM; 80 return -ENOMEM;
81 81
@@ -236,7 +236,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
236 perf_session__fprintf_dsos(session, stdout); 236 perf_session__fprintf_dsos(session, stdout);
237 237
238 total_nr_samples = 0; 238 total_nr_samples = 0;
239 evlist__for_each(session->evlist, pos) { 239 evlist__for_each_entry(session->evlist, pos) {
240 struct hists *hists = evsel__hists(pos); 240 struct hists *hists = evsel__hists(pos);
241 u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; 241 u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
242 242
@@ -339,6 +339,9 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
339 "Show event group information together"), 339 "Show event group information together"),
340 OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, 340 OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
341 "Show a column with the sum of periods"), 341 "Show a column with the sum of periods"),
342 OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
343 "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
344 stdio__config_color, "always"),
342 OPT_END() 345 OPT_END()
343 }; 346 };
344 int ret = hists__init(); 347 int ret = hists__init();
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index d75bded21fe0..30e2b2cb2421 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -209,7 +209,7 @@ static int build_id_cache__purge_path(const char *pathname)
209 if (err) 209 if (err)
210 goto out; 210 goto out;
211 211
212 strlist__for_each(pos, list) { 212 strlist__for_each_entry(pos, list) {
213 err = build_id_cache__remove_s(pos->s); 213 err = build_id_cache__remove_s(pos->s);
214 pr_debug("Removing %s %s: %s\n", pos->s, pathname, 214 pr_debug("Removing %s %s: %s\n", pos->s, pathname,
215 err ? "FAIL" : "Ok"); 215 err ? "FAIL" : "Ok");
@@ -343,7 +343,7 @@ int cmd_buildid_cache(int argc, const char **argv,
343 if (add_name_list_str) { 343 if (add_name_list_str) {
344 list = strlist__new(add_name_list_str, NULL); 344 list = strlist__new(add_name_list_str, NULL);
345 if (list) { 345 if (list) {
346 strlist__for_each(pos, list) 346 strlist__for_each_entry(pos, list)
347 if (build_id_cache__add_file(pos->s)) { 347 if (build_id_cache__add_file(pos->s)) {
348 if (errno == EEXIST) { 348 if (errno == EEXIST) {
349 pr_debug("%s already in the cache\n", 349 pr_debug("%s already in the cache\n",
@@ -351,7 +351,7 @@ int cmd_buildid_cache(int argc, const char **argv,
351 continue; 351 continue;
352 } 352 }
353 pr_warning("Couldn't add %s: %s\n", 353 pr_warning("Couldn't add %s: %s\n",
354 pos->s, strerror_r(errno, sbuf, sizeof(sbuf))); 354 pos->s, str_error_r(errno, sbuf, sizeof(sbuf)));
355 } 355 }
356 356
357 strlist__delete(list); 357 strlist__delete(list);
@@ -361,7 +361,7 @@ int cmd_buildid_cache(int argc, const char **argv,
361 if (remove_name_list_str) { 361 if (remove_name_list_str) {
362 list = strlist__new(remove_name_list_str, NULL); 362 list = strlist__new(remove_name_list_str, NULL);
363 if (list) { 363 if (list) {
364 strlist__for_each(pos, list) 364 strlist__for_each_entry(pos, list)
365 if (build_id_cache__remove_file(pos->s)) { 365 if (build_id_cache__remove_file(pos->s)) {
366 if (errno == ENOENT) { 366 if (errno == ENOENT) {
367 pr_debug("%s wasn't in the cache\n", 367 pr_debug("%s wasn't in the cache\n",
@@ -369,7 +369,7 @@ int cmd_buildid_cache(int argc, const char **argv,
369 continue; 369 continue;
370 } 370 }
371 pr_warning("Couldn't remove %s: %s\n", 371 pr_warning("Couldn't remove %s: %s\n",
372 pos->s, strerror_r(errno, sbuf, sizeof(sbuf))); 372 pos->s, str_error_r(errno, sbuf, sizeof(sbuf)));
373 } 373 }
374 374
375 strlist__delete(list); 375 strlist__delete(list);
@@ -379,7 +379,7 @@ int cmd_buildid_cache(int argc, const char **argv,
379 if (purge_name_list_str) { 379 if (purge_name_list_str) {
380 list = strlist__new(purge_name_list_str, NULL); 380 list = strlist__new(purge_name_list_str, NULL);
381 if (list) { 381 if (list) {
382 strlist__for_each(pos, list) 382 strlist__for_each_entry(pos, list)
383 if (build_id_cache__purge_path(pos->s)) { 383 if (build_id_cache__purge_path(pos->s)) {
384 if (errno == ENOENT) { 384 if (errno == ENOENT) {
385 pr_debug("%s wasn't in the cache\n", 385 pr_debug("%s wasn't in the cache\n",
@@ -387,7 +387,7 @@ int cmd_buildid_cache(int argc, const char **argv,
387 continue; 387 continue;
388 } 388 }
389 pr_warning("Couldn't remove %s: %s\n", 389 pr_warning("Couldn't remove %s: %s\n",
390 pos->s, strerror_r(errno, sbuf, sizeof(sbuf))); 390 pos->s, str_error_r(errno, sbuf, sizeof(sbuf)));
391 } 391 }
392 392
393 strlist__delete(list); 393 strlist__delete(list);
@@ -400,7 +400,7 @@ int cmd_buildid_cache(int argc, const char **argv,
400 if (update_name_list_str) { 400 if (update_name_list_str) {
401 list = strlist__new(update_name_list_str, NULL); 401 list = strlist__new(update_name_list_str, NULL);
402 if (list) { 402 if (list) {
403 strlist__for_each(pos, list) 403 strlist__for_each_entry(pos, list)
404 if (build_id_cache__update_file(pos->s)) { 404 if (build_id_cache__update_file(pos->s)) {
405 if (errno == ENOENT) { 405 if (errno == ENOENT) {
406 pr_debug("%s wasn't in the cache\n", 406 pr_debug("%s wasn't in the cache\n",
@@ -408,7 +408,7 @@ int cmd_buildid_cache(int argc, const char **argv,
408 continue; 408 continue;
409 } 409 }
410 pr_warning("Couldn't update %s: %s\n", 410 pr_warning("Couldn't update %s: %s\n",
411 pos->s, strerror_r(errno, sbuf, sizeof(sbuf))); 411 pos->s, str_error_r(errno, sbuf, sizeof(sbuf)));
412 } 412 }
413 413
414 strlist__delete(list); 414 strlist__delete(list);
@@ -419,8 +419,7 @@ int cmd_buildid_cache(int argc, const char **argv,
419 pr_warning("Couldn't add %s\n", kcore_filename); 419 pr_warning("Couldn't add %s\n", kcore_filename);
420 420
421out: 421out:
422 if (session) 422 perf_session__delete(session);
423 perf_session__delete(session);
424 423
425 return ret; 424 return ret;
426} 425}
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index fe1b77fa21f9..e4207a23b52c 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -37,23 +37,16 @@ static int show_config(struct perf_config_set *set)
37{ 37{
38 struct perf_config_section *section; 38 struct perf_config_section *section;
39 struct perf_config_item *item; 39 struct perf_config_item *item;
40 struct list_head *sections;
41 40
42 if (set == NULL) 41 if (set == NULL)
43 return -1; 42 return -1;
44 43
45 sections = &set->sections; 44 perf_config_set__for_each_entry(set, section, item) {
46 if (list_empty(sections)) 45 char *value = item->value;
47 return -1;
48
49 list_for_each_entry(section, sections, node) {
50 list_for_each_entry(item, &section->items, node) {
51 char *value = item->value;
52 46
53 if (value) 47 if (value)
54 printf("%s.%s=%s\n", section->name, 48 printf("%s.%s=%s\n", section->name,
55 item->name, value); 49 item->name, value);
56 }
57 } 50 }
58 51
59 return 0; 52 return 0;
@@ -80,6 +73,10 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
80 else if (use_user_config) 73 else if (use_user_config)
81 config_exclusive_filename = user_config; 74 config_exclusive_filename = user_config;
82 75
76 /*
77 * At only 'config' sub-command, individually use the config set
78 * because of reinitializing with options config file location.
79 */
83 set = perf_config_set__new(); 80 set = perf_config_set__new();
84 if (!set) { 81 if (!set) {
85 ret = -1; 82 ret = -1;
diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c
index b97bc1518b44..7ad6e17ac6b3 100644
--- a/tools/perf/builtin-data.c
+++ b/tools/perf/builtin-data.c
@@ -3,6 +3,7 @@
3#include "perf.h" 3#include "perf.h"
4#include "debug.h" 4#include "debug.h"
5#include <subcmd/parse-options.h> 5#include <subcmd/parse-options.h>
6#include "data-convert.h"
6#include "data-convert-bt.h" 7#include "data-convert-bt.h"
7 8
8typedef int (*data_cmd_fn_t)(int argc, const char **argv, const char *prefix); 9typedef int (*data_cmd_fn_t)(int argc, const char **argv, const char *prefix);
@@ -53,14 +54,18 @@ static int cmd_data_convert(int argc, const char **argv,
53 const char *prefix __maybe_unused) 54 const char *prefix __maybe_unused)
54{ 55{
55 const char *to_ctf = NULL; 56 const char *to_ctf = NULL;
56 bool force = false; 57 struct perf_data_convert_opts opts = {
58 .force = false,
59 .all = false,
60 };
57 const struct option options[] = { 61 const struct option options[] = {
58 OPT_INCR('v', "verbose", &verbose, "be more verbose"), 62 OPT_INCR('v', "verbose", &verbose, "be more verbose"),
59 OPT_STRING('i', "input", &input_name, "file", "input file name"), 63 OPT_STRING('i', "input", &input_name, "file", "input file name"),
60#ifdef HAVE_LIBBABELTRACE_SUPPORT 64#ifdef HAVE_LIBBABELTRACE_SUPPORT
61 OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"), 65 OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
62#endif 66#endif
63 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), 67 OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"),
68 OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"),
64 OPT_END() 69 OPT_END()
65 }; 70 };
66 71
@@ -78,7 +83,7 @@ static int cmd_data_convert(int argc, const char **argv,
78 83
79 if (to_ctf) { 84 if (to_ctf) {
80#ifdef HAVE_LIBBABELTRACE_SUPPORT 85#ifdef HAVE_LIBBABELTRACE_SUPPORT
81 return bt_convert__perf2ctf(input_name, to_ctf, force); 86 return bt_convert__perf2ctf(input_name, to_ctf, &opts);
82#else 87#else
83 pr_err("The libbabeltrace support is not compiled in.\n"); 88 pr_err("The libbabeltrace support is not compiled in.\n");
84 return -1; 89 return -1;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index f7645a42708e..21ee753211ad 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -310,16 +310,6 @@ static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
310 return -1; 310 return -1;
311} 311}
312 312
313static int hists__add_entry(struct hists *hists,
314 struct addr_location *al,
315 struct perf_sample *sample)
316{
317 if (__hists__add_entry(hists, al, NULL, NULL, NULL,
318 sample, true) != NULL)
319 return 0;
320 return -ENOMEM;
321}
322
323static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, 313static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
324 union perf_event *event, 314 union perf_event *event,
325 struct perf_sample *sample, 315 struct perf_sample *sample,
@@ -336,7 +326,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
336 return -1; 326 return -1;
337 } 327 }
338 328
339 if (hists__add_entry(hists, &al, sample)) { 329 if (!hists__add_entry(hists, &al, NULL, NULL, NULL, sample, true)) {
340 pr_warning("problem incrementing symbol period, skipping event\n"); 330 pr_warning("problem incrementing symbol period, skipping event\n");
341 goto out_put; 331 goto out_put;
342 } 332 }
@@ -373,7 +363,7 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
373{ 363{
374 struct perf_evsel *e; 364 struct perf_evsel *e;
375 365
376 evlist__for_each(evlist, e) { 366 evlist__for_each_entry(evlist, e) {
377 if (perf_evsel__match2(evsel, e)) 367 if (perf_evsel__match2(evsel, e))
378 return e; 368 return e;
379 } 369 }
@@ -385,7 +375,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
385{ 375{
386 struct perf_evsel *evsel; 376 struct perf_evsel *evsel;
387 377
388 evlist__for_each(evlist, evsel) { 378 evlist__for_each_entry(evlist, evsel) {
389 struct hists *hists = evsel__hists(evsel); 379 struct hists *hists = evsel__hists(evsel);
390 380
391 hists__collapse_resort(hists, NULL); 381 hists__collapse_resort(hists, NULL);
@@ -666,7 +656,8 @@ static void hists__process(struct hists *hists)
666 hists__precompute(hists); 656 hists__precompute(hists);
667 hists__output_resort(hists, NULL); 657 hists__output_resort(hists, NULL);
668 658
669 hists__fprintf(hists, true, 0, 0, 0, stdout); 659 hists__fprintf(hists, true, 0, 0, 0, stdout,
660 symbol_conf.use_callchain);
670} 661}
671 662
672static void data__fprintf(void) 663static void data__fprintf(void)
@@ -690,7 +681,7 @@ static void data_process(void)
690 struct perf_evsel *evsel_base; 681 struct perf_evsel *evsel_base;
691 bool first = true; 682 bool first = true;
692 683
693 evlist__for_each(evlist_base, evsel_base) { 684 evlist__for_each_entry(evlist_base, evsel_base) {
694 struct hists *hists_base = evsel__hists(evsel_base); 685 struct hists *hists_base = evsel__hists(evsel_base);
695 struct data__file *d; 686 struct data__file *d;
696 int i; 687 int i;
@@ -765,9 +756,7 @@ static int __cmd_diff(void)
765 756
766 out_delete: 757 out_delete:
767 data__for_each_file(i, d) { 758 data__for_each_file(i, d) {
768 if (d->session) 759 perf_session__delete(d->session);
769 perf_session__delete(d->session);
770
771 data__free(d); 760 data__free(d);
772 } 761 }
773 762
@@ -1044,7 +1033,7 @@ static int hpp__entry_global(struct perf_hpp_fmt *_fmt, struct perf_hpp *hpp,
1044} 1033}
1045 1034
1046static int hpp__header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 1035static int hpp__header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1047 struct perf_evsel *evsel __maybe_unused) 1036 struct hists *hists __maybe_unused)
1048{ 1037{
1049 struct diff_hpp_fmt *dfmt = 1038 struct diff_hpp_fmt *dfmt =
1050 container_of(fmt, struct diff_hpp_fmt, fmt); 1039 container_of(fmt, struct diff_hpp_fmt, fmt);
@@ -1055,7 +1044,7 @@ static int hpp__header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1055 1044
1056static int hpp__width(struct perf_hpp_fmt *fmt, 1045static int hpp__width(struct perf_hpp_fmt *fmt,
1057 struct perf_hpp *hpp __maybe_unused, 1046 struct perf_hpp *hpp __maybe_unused,
1058 struct perf_evsel *evsel __maybe_unused) 1047 struct hists *hists __maybe_unused)
1059{ 1048{
1060 struct diff_hpp_fmt *dfmt = 1049 struct diff_hpp_fmt *dfmt =
1061 container_of(fmt, struct diff_hpp_fmt, fmt); 1050 container_of(fmt, struct diff_hpp_fmt, fmt);
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index 8a31f511e1a0..e09c4287fe87 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -32,7 +32,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details
32 if (session == NULL) 32 if (session == NULL)
33 return -1; 33 return -1;
34 34
35 evlist__for_each(session->evlist, pos) { 35 evlist__for_each_entry(session->evlist, pos) {
36 perf_evsel__fprintf(pos, details, stdout); 36 perf_evsel__fprintf(pos, details, stdout);
37 37
38 if (pos->attr.type == PERF_TYPE_TRACEPOINT) 38 if (pos->attr.type == PERF_TYPE_TRACEPOINT)
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index f9830c902b78..3bdb2c78a21b 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -4,7 +4,7 @@
4 * Builtin help command 4 * Builtin help command
5 */ 5 */
6#include "perf.h" 6#include "perf.h"
7#include "util/cache.h" 7#include "util/config.h"
8#include "builtin.h" 8#include "builtin.h"
9#include <subcmd/exec-cmd.h> 9#include <subcmd/exec-cmd.h>
10#include "common-cmds.h" 10#include "common-cmds.h"
@@ -117,7 +117,7 @@ static void exec_woman_emacs(const char *path, const char *page)
117 free(man_page); 117 free(man_page);
118 } 118 }
119 warning("failed to exec '%s': %s", path, 119 warning("failed to exec '%s': %s", path,
120 strerror_r(errno, sbuf, sizeof(sbuf))); 120 str_error_r(errno, sbuf, sizeof(sbuf)));
121 } 121 }
122} 122}
123 123
@@ -150,7 +150,7 @@ static void exec_man_konqueror(const char *path, const char *page)
150 free(man_page); 150 free(man_page);
151 } 151 }
152 warning("failed to exec '%s': %s", path, 152 warning("failed to exec '%s': %s", path,
153 strerror_r(errno, sbuf, sizeof(sbuf))); 153 str_error_r(errno, sbuf, sizeof(sbuf)));
154 } 154 }
155} 155}
156 156
@@ -162,7 +162,7 @@ static void exec_man_man(const char *path, const char *page)
162 path = "man"; 162 path = "man";
163 execlp(path, "man", page, NULL); 163 execlp(path, "man", page, NULL);
164 warning("failed to exec '%s': %s", path, 164 warning("failed to exec '%s': %s", path,
165 strerror_r(errno, sbuf, sizeof(sbuf))); 165 str_error_r(errno, sbuf, sizeof(sbuf)));
166} 166}
167 167
168static void exec_man_cmd(const char *cmd, const char *page) 168static void exec_man_cmd(const char *cmd, const char *page)
@@ -175,7 +175,7 @@ static void exec_man_cmd(const char *cmd, const char *page)
175 free(shell_cmd); 175 free(shell_cmd);
176 } 176 }
177 warning("failed to exec '%s': %s", cmd, 177 warning("failed to exec '%s': %s", cmd,
178 strerror_r(errno, sbuf, sizeof(sbuf))); 178 str_error_r(errno, sbuf, sizeof(sbuf)));
179} 179}
180 180
181static void add_man_viewer(const char *name) 181static void add_man_viewer(const char *name)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index e5afa8fe1bf1..73c1c4cc3600 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -562,7 +562,7 @@ static void strip_init(struct perf_inject *inject)
562 562
563 inject->tool.context_switch = perf_event__drop; 563 inject->tool.context_switch = perf_event__drop;
564 564
565 evlist__for_each(evlist, evsel) 565 evlist__for_each_entry(evlist, evsel)
566 evsel->handler = drop_sample; 566 evsel->handler = drop_sample;
567} 567}
568 568
@@ -590,7 +590,7 @@ static bool ok_to_remove(struct perf_evlist *evlist,
590 if (!has_tracking(evsel_to_remove)) 590 if (!has_tracking(evsel_to_remove))
591 return true; 591 return true;
592 592
593 evlist__for_each(evlist, evsel) { 593 evlist__for_each_entry(evlist, evsel) {
594 if (evsel->handler != drop_sample) { 594 if (evsel->handler != drop_sample) {
595 cnt += 1; 595 cnt += 1;
596 if ((evsel->attr.sample_type & COMPAT_MASK) == 596 if ((evsel->attr.sample_type & COMPAT_MASK) ==
@@ -608,7 +608,7 @@ static void strip_fini(struct perf_inject *inject)
608 struct perf_evsel *evsel, *tmp; 608 struct perf_evsel *evsel, *tmp;
609 609
610 /* Remove non-synthesized evsels if possible */ 610 /* Remove non-synthesized evsels if possible */
611 evlist__for_each_safe(evlist, tmp, evsel) { 611 evlist__for_each_entry_safe(evlist, tmp, evsel) {
612 if (evsel->handler == drop_sample && 612 if (evsel->handler == drop_sample &&
613 ok_to_remove(evlist, evsel)) { 613 ok_to_remove(evlist, evsel)) {
614 pr_debug("Deleting %s\n", perf_evsel__name(evsel)); 614 pr_debug("Deleting %s\n", perf_evsel__name(evsel));
@@ -643,7 +643,7 @@ static int __cmd_inject(struct perf_inject *inject)
643 } else if (inject->sched_stat) { 643 } else if (inject->sched_stat) {
644 struct perf_evsel *evsel; 644 struct perf_evsel *evsel;
645 645
646 evlist__for_each(session->evlist, evsel) { 646 evlist__for_each_entry(session->evlist, evsel) {
647 const char *name = perf_evsel__name(evsel); 647 const char *name = perf_evsel__name(evsel);
648 648
649 if (!strcmp(name, "sched:sched_switch")) { 649 if (!strcmp(name, "sched:sched_switch")) {
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 58adfee230de..fdde1bd3e306 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -4,7 +4,7 @@
4#include "util/evlist.h" 4#include "util/evlist.h"
5#include "util/evsel.h" 5#include "util/evsel.h"
6#include "util/util.h" 6#include "util/util.h"
7#include "util/cache.h" 7#include "util/config.h"
8#include "util/symbol.h" 8#include "util/symbol.h"
9#include "util/thread.h" 9#include "util/thread.h"
10#include "util/header.h" 10#include "util/header.h"
@@ -608,6 +608,7 @@ static const struct {
608 const char *compact; 608 const char *compact;
609} gfp_compact_table[] = { 609} gfp_compact_table[] = {
610 { "GFP_TRANSHUGE", "THP" }, 610 { "GFP_TRANSHUGE", "THP" },
611 { "GFP_TRANSHUGE_LIGHT", "THL" },
611 { "GFP_HIGHUSER_MOVABLE", "HUM" }, 612 { "GFP_HIGHUSER_MOVABLE", "HUM" },
612 { "GFP_HIGHUSER", "HU" }, 613 { "GFP_HIGHUSER", "HU" },
613 { "GFP_USER", "U" }, 614 { "GFP_USER", "U" },
@@ -1354,7 +1355,7 @@ static int __cmd_kmem(struct perf_session *session)
1354 goto out; 1355 goto out;
1355 } 1356 }
1356 1357
1357 evlist__for_each(session->evlist, evsel) { 1358 evlist__for_each_entry(session->evlist, evsel) {
1358 if (!strcmp(perf_evsel__name(evsel), "kmem:mm_page_alloc") && 1359 if (!strcmp(perf_evsel__name(evsel), "kmem:mm_page_alloc") &&
1359 perf_evsel__field(evsel, "pfn")) { 1360 perf_evsel__field(evsel, "pfn")) {
1360 use_pfn = true; 1361 use_pfn = true;
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 6487c06d2708..5e2127e04f83 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -988,7 +988,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
988 * Note: exclude_{guest,host} do not apply here. 988 * Note: exclude_{guest,host} do not apply here.
989 * This command processes KVM tracepoints from host only 989 * This command processes KVM tracepoints from host only
990 */ 990 */
991 evlist__for_each(evlist, pos) { 991 evlist__for_each_entry(evlist, pos) {
992 struct perf_event_attr *attr = &pos->attr; 992 struct perf_event_attr *attr = &pos->attr;
993 993
994 /* make sure these *are* set */ 994 /* make sure these *are* set */
@@ -1018,13 +1018,13 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
1018 err = perf_evlist__open(evlist); 1018 err = perf_evlist__open(evlist);
1019 if (err < 0) { 1019 if (err < 0) {
1020 printf("Couldn't create the events: %s\n", 1020 printf("Couldn't create the events: %s\n",
1021 strerror_r(errno, sbuf, sizeof(sbuf))); 1021 str_error_r(errno, sbuf, sizeof(sbuf)));
1022 goto out; 1022 goto out;
1023 } 1023 }
1024 1024
1025 if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { 1025 if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) {
1026 ui__error("Failed to mmap the events: %s\n", 1026 ui__error("Failed to mmap the events: %s\n",
1027 strerror_r(errno, sbuf, sizeof(sbuf))); 1027 str_error_r(errno, sbuf, sizeof(sbuf)));
1028 perf_evlist__close(evlist); 1028 perf_evlist__close(evlist);
1029 goto out; 1029 goto out;
1030 } 1030 }
@@ -1426,11 +1426,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1426 err = kvm_events_live_report(kvm); 1426 err = kvm_events_live_report(kvm);
1427 1427
1428out: 1428out:
1429 if (kvm->session) 1429 perf_session__delete(kvm->session);
1430 perf_session__delete(kvm->session);
1431 kvm->session = NULL; 1430 kvm->session = NULL;
1432 if (kvm->evlist) 1431 perf_evlist__delete(kvm->evlist);
1433 perf_evlist__delete(kvm->evlist);
1434 1432
1435 return err; 1433 return err;
1436} 1434}
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index 5e22db4684b8..88ee419e5189 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -25,7 +25,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
25 OPT_END() 25 OPT_END()
26 }; 26 };
27 const char * const list_usage[] = { 27 const char * const list_usage[] = {
28 "perf list [hw|sw|cache|tracepoint|pmu|event_glob]", 28 "perf list [hw|sw|cache|tracepoint|pmu|sdt|event_glob]",
29 NULL 29 NULL
30 }; 30 };
31 31
@@ -62,6 +62,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
62 print_hwcache_events(NULL, raw_dump); 62 print_hwcache_events(NULL, raw_dump);
63 else if (strcmp(argv[i], "pmu") == 0) 63 else if (strcmp(argv[i], "pmu") == 0)
64 print_pmu_events(NULL, raw_dump); 64 print_pmu_events(NULL, raw_dump);
65 else if (strcmp(argv[i], "sdt") == 0)
66 print_sdt_events(NULL, NULL, raw_dump);
65 else if ((sep = strchr(argv[i], ':')) != NULL) { 67 else if ((sep = strchr(argv[i], ':')) != NULL) {
66 int sep_idx; 68 int sep_idx;
67 69
@@ -76,6 +78,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
76 78
77 s[sep_idx] = '\0'; 79 s[sep_idx] = '\0';
78 print_tracepoint_events(s, s + sep_idx + 1, raw_dump); 80 print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
81 print_sdt_events(s, s + sep_idx + 1, raw_dump);
79 free(s); 82 free(s);
80 } else { 83 } else {
81 if (asprintf(&s, "*%s*", argv[i]) < 0) { 84 if (asprintf(&s, "*%s*", argv[i]) < 0) {
@@ -89,6 +92,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
89 print_hwcache_events(s, raw_dump); 92 print_hwcache_events(s, raw_dump);
90 print_pmu_events(s, raw_dump); 93 print_pmu_events(s, raw_dump);
91 print_tracepoint_events(NULL, s, raw_dump); 94 print_tracepoint_events(NULL, s, raw_dump);
95 print_sdt_events(NULL, s, raw_dump);
92 free(s); 96 free(s);
93 } 97 }
94 } 98 }
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 1dc140c5481d..d608a2c9e48c 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -67,6 +67,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
67 OPT_CALLBACK('e', "event", &mem, "event", 67 OPT_CALLBACK('e', "event", &mem, "event",
68 "event selector. use 'perf mem record -e list' to list available events", 68 "event selector. use 'perf mem record -e list' to list available events",
69 parse_record_events), 69 parse_record_events),
70 OPT_UINTEGER(0, "ldlat", &perf_mem_events__loads_ldlat, "mem-loads latency"),
70 OPT_INCR('v', "verbose", &verbose, 71 OPT_INCR('v', "verbose", &verbose,
71 "be more verbose (show counter open errors, etc)"), 72 "be more verbose (show counter open errors, etc)"),
72 OPT_BOOLEAN('U', "--all-user", &all_user, "collect only user level data"), 73 OPT_BOOLEAN('U', "--all-user", &all_user, "collect only user level data"),
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 9af859b28b15..ee5b42173ba3 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -44,7 +44,7 @@
44 44
45#define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*" 45#define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"
46#define DEFAULT_FUNC_FILTER "!_*" 46#define DEFAULT_FUNC_FILTER "!_*"
47#define DEFAULT_LIST_FILTER "*:*" 47#define DEFAULT_LIST_FILTER "*"
48 48
49/* Session management structure */ 49/* Session management structure */
50static struct { 50static struct {
@@ -308,7 +308,7 @@ static void pr_err_with_code(const char *msg, int err)
308 308
309 pr_err("%s", msg); 309 pr_err("%s", msg);
310 pr_debug(" Reason: %s (Code: %d)", 310 pr_debug(" Reason: %s (Code: %d)",
311 strerror_r(-err, sbuf, sizeof(sbuf)), err); 311 str_error_r(-err, sbuf, sizeof(sbuf)), err);
312 pr_err("\n"); 312 pr_err("\n");
313} 313}
314 314
@@ -363,6 +363,32 @@ out_cleanup:
363 return ret; 363 return ret;
364} 364}
365 365
366static int del_perf_probe_caches(struct strfilter *filter)
367{
368 struct probe_cache *cache;
369 struct strlist *bidlist;
370 struct str_node *nd;
371 int ret;
372
373 bidlist = build_id_cache__list_all(false);
374 if (!bidlist) {
375 ret = -errno;
376 pr_debug("Failed to get buildids: %d\n", ret);
377 return ret ?: -ENOMEM;
378 }
379
380 strlist__for_each_entry(nd, bidlist) {
381 cache = probe_cache__new(nd->s);
382 if (!cache)
383 continue;
384 if (probe_cache__filter_purge(cache, filter) < 0 ||
385 probe_cache__commit(cache) < 0)
386 pr_warning("Failed to remove entries for %s\n", nd->s);
387 probe_cache__delete(cache);
388 }
389 return 0;
390}
391
366static int perf_del_probe_events(struct strfilter *filter) 392static int perf_del_probe_events(struct strfilter *filter)
367{ 393{
368 int ret, ret2, ufd = -1, kfd = -1; 394 int ret, ret2, ufd = -1, kfd = -1;
@@ -375,6 +401,9 @@ static int perf_del_probe_events(struct strfilter *filter)
375 401
376 pr_debug("Delete filter: \'%s\'\n", str); 402 pr_debug("Delete filter: \'%s\'\n", str);
377 403
404 if (probe_conf.cache)
405 return del_perf_probe_caches(filter);
406
378 /* Get current event names */ 407 /* Get current event names */
379 ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW); 408 ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
380 if (ret < 0) 409 if (ret < 0)
@@ -389,7 +418,7 @@ static int perf_del_probe_events(struct strfilter *filter)
389 418
390 ret = probe_file__get_events(kfd, filter, klist); 419 ret = probe_file__get_events(kfd, filter, klist);
391 if (ret == 0) { 420 if (ret == 0) {
392 strlist__for_each(ent, klist) 421 strlist__for_each_entry(ent, klist)
393 pr_info("Removed event: %s\n", ent->s); 422 pr_info("Removed event: %s\n", ent->s);
394 423
395 ret = probe_file__del_strlist(kfd, klist); 424 ret = probe_file__del_strlist(kfd, klist);
@@ -399,7 +428,7 @@ static int perf_del_probe_events(struct strfilter *filter)
399 428
400 ret2 = probe_file__get_events(ufd, filter, ulist); 429 ret2 = probe_file__get_events(ufd, filter, ulist);
401 if (ret2 == 0) { 430 if (ret2 == 0) {
402 strlist__for_each(ent, ulist) 431 strlist__for_each_entry(ent, ulist)
403 pr_info("Removed event: %s\n", ent->s); 432 pr_info("Removed event: %s\n", ent->s);
404 433
405 ret2 = probe_file__del_strlist(ufd, ulist); 434 ret2 = probe_file__del_strlist(ufd, ulist);
@@ -512,6 +541,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
512 "Enable symbol demangling"), 541 "Enable symbol demangling"),
513 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 542 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
514 "Enable kernel symbol demangling"), 543 "Enable kernel symbol demangling"),
544 OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"),
515 OPT_END() 545 OPT_END()
516 }; 546 };
517 int ret; 547 int ret;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index dc3fcb597e4c..8f2c16d9275f 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -13,6 +13,7 @@
13#include "util/util.h" 13#include "util/util.h"
14#include <subcmd/parse-options.h> 14#include <subcmd/parse-options.h>
15#include "util/parse-events.h" 15#include "util/parse-events.h"
16#include "util/config.h"
16 17
17#include "util/callchain.h" 18#include "util/callchain.h"
18#include "util/cgroup.h" 19#include "util/cgroup.h"
@@ -118,11 +119,10 @@ backward_rb_find_range(void *buf, int mask, u64 head, u64 *start, u64 *end)
118} 119}
119 120
120static int 121static int
121rb_find_range(struct perf_evlist *evlist, 122rb_find_range(void *data, int mask, u64 head, u64 old,
122 void *data, int mask, u64 head, u64 old, 123 u64 *start, u64 *end, bool backward)
123 u64 *start, u64 *end)
124{ 124{
125 if (!evlist->backward) { 125 if (!backward) {
126 *start = old; 126 *start = old;
127 *end = head; 127 *end = head;
128 return 0; 128 return 0;
@@ -131,9 +131,10 @@ rb_find_range(struct perf_evlist *evlist,
131 return backward_rb_find_range(data, mask, head, start, end); 131 return backward_rb_find_range(data, mask, head, start, end);
132} 132}
133 133
134static int record__mmap_read(struct record *rec, int idx) 134static int
135record__mmap_read(struct record *rec, struct perf_mmap *md,
136 bool overwrite, bool backward)
135{ 137{
136 struct perf_mmap *md = &rec->evlist->mmap[idx];
137 u64 head = perf_mmap__read_head(md); 138 u64 head = perf_mmap__read_head(md);
138 u64 old = md->prev; 139 u64 old = md->prev;
139 u64 end = head, start = old; 140 u64 end = head, start = old;
@@ -142,8 +143,8 @@ static int record__mmap_read(struct record *rec, int idx)
142 void *buf; 143 void *buf;
143 int rc = 0; 144 int rc = 0;
144 145
145 if (rb_find_range(rec->evlist, data, md->mask, head, 146 if (rb_find_range(data, md->mask, head,
146 old, &start, &end)) 147 old, &start, &end, backward))
147 return -1; 148 return -1;
148 149
149 if (start == end) 150 if (start == end)
@@ -156,7 +157,7 @@ static int record__mmap_read(struct record *rec, int idx)
156 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); 157 WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
157 158
158 md->prev = head; 159 md->prev = head;
159 perf_evlist__mmap_consume(rec->evlist, idx); 160 perf_mmap__consume(md, overwrite || backward);
160 return 0; 161 return 0;
161 } 162 }
162 163
@@ -181,7 +182,7 @@ static int record__mmap_read(struct record *rec, int idx)
181 } 182 }
182 183
183 md->prev = head; 184 md->prev = head;
184 perf_evlist__mmap_consume(rec->evlist, idx); 185 perf_mmap__consume(md, overwrite || backward);
185out: 186out:
186 return rc; 187 return rc;
187} 188}
@@ -341,6 +342,40 @@ int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
341 342
342#endif 343#endif
343 344
345static int record__mmap_evlist(struct record *rec,
346 struct perf_evlist *evlist)
347{
348 struct record_opts *opts = &rec->opts;
349 char msg[512];
350
351 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
352 opts->auxtrace_mmap_pages,
353 opts->auxtrace_snapshot_mode) < 0) {
354 if (errno == EPERM) {
355 pr_err("Permission error mapping pages.\n"
356 "Consider increasing "
357 "/proc/sys/kernel/perf_event_mlock_kb,\n"
358 "or try again with a smaller value of -m/--mmap_pages.\n"
359 "(current value: %u,%u)\n",
360 opts->mmap_pages, opts->auxtrace_mmap_pages);
361 return -errno;
362 } else {
363 pr_err("failed to mmap with %d (%s)\n", errno,
364 str_error_r(errno, msg, sizeof(msg)));
365 if (errno)
366 return -errno;
367 else
368 return -EINVAL;
369 }
370 }
371 return 0;
372}
373
374static int record__mmap(struct record *rec)
375{
376 return record__mmap_evlist(rec, rec->evlist);
377}
378
344static int record__open(struct record *rec) 379static int record__open(struct record *rec)
345{ 380{
346 char msg[512]; 381 char msg[512];
@@ -352,7 +387,7 @@ static int record__open(struct record *rec)
352 387
353 perf_evlist__config(evlist, opts, &callchain_param); 388 perf_evlist__config(evlist, opts, &callchain_param);
354 389
355 evlist__for_each(evlist, pos) { 390 evlist__for_each_entry(evlist, pos) {
356try_again: 391try_again:
357 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { 392 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
358 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { 393 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
@@ -372,32 +407,14 @@ try_again:
372 if (perf_evlist__apply_filters(evlist, &pos)) { 407 if (perf_evlist__apply_filters(evlist, &pos)) {
373 error("failed to set filter \"%s\" on event %s with %d (%s)\n", 408 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
374 pos->filter, perf_evsel__name(pos), errno, 409 pos->filter, perf_evsel__name(pos), errno,
375 strerror_r(errno, msg, sizeof(msg))); 410 str_error_r(errno, msg, sizeof(msg)));
376 rc = -1; 411 rc = -1;
377 goto out; 412 goto out;
378 } 413 }
379 414
380 if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, 415 rc = record__mmap(rec);
381 opts->auxtrace_mmap_pages, 416 if (rc)
382 opts->auxtrace_snapshot_mode) < 0) {
383 if (errno == EPERM) {
384 pr_err("Permission error mapping pages.\n"
385 "Consider increasing "
386 "/proc/sys/kernel/perf_event_mlock_kb,\n"
387 "or try again with a smaller value of -m/--mmap_pages.\n"
388 "(current value: %u,%u)\n",
389 opts->mmap_pages, opts->auxtrace_mmap_pages);
390 rc = -errno;
391 } else {
392 pr_err("failed to mmap with %d (%s)\n", errno,
393 strerror_r(errno, msg, sizeof(msg)));
394 if (errno)
395 rc = -errno;
396 else
397 rc = -EINVAL;
398 }
399 goto out; 417 goto out;
400 }
401 418
402 session->evlist = evlist; 419 session->evlist = evlist;
403 perf_session__set_id_hdr_size(session); 420 perf_session__set_id_hdr_size(session);
@@ -481,17 +498,30 @@ static struct perf_event_header finished_round_event = {
481 .type = PERF_RECORD_FINISHED_ROUND, 498 .type = PERF_RECORD_FINISHED_ROUND,
482}; 499};
483 500
484static int record__mmap_read_all(struct record *rec) 501static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist,
502 bool backward)
485{ 503{
486 u64 bytes_written = rec->bytes_written; 504 u64 bytes_written = rec->bytes_written;
487 int i; 505 int i;
488 int rc = 0; 506 int rc = 0;
507 struct perf_mmap *maps;
489 508
490 for (i = 0; i < rec->evlist->nr_mmaps; i++) { 509 if (!evlist)
491 struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap; 510 return 0;
492 511
493 if (rec->evlist->mmap[i].base) { 512 maps = backward ? evlist->backward_mmap : evlist->mmap;
494 if (record__mmap_read(rec, i) != 0) { 513 if (!maps)
514 return 0;
515
516 if (backward && evlist->bkw_mmap_state != BKW_MMAP_DATA_PENDING)
517 return 0;
518
519 for (i = 0; i < evlist->nr_mmaps; i++) {
520 struct auxtrace_mmap *mm = &maps[i].auxtrace_mmap;
521
522 if (maps[i].base) {
523 if (record__mmap_read(rec, &maps[i],
524 evlist->overwrite, backward) != 0) {
495 rc = -1; 525 rc = -1;
496 goto out; 526 goto out;
497 } 527 }
@@ -511,10 +541,23 @@ static int record__mmap_read_all(struct record *rec)
511 if (bytes_written != rec->bytes_written) 541 if (bytes_written != rec->bytes_written)
512 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event)); 542 rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
513 543
544 if (backward)
545 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY);
514out: 546out:
515 return rc; 547 return rc;
516} 548}
517 549
550static int record__mmap_read_all(struct record *rec)
551{
552 int err;
553
554 err = record__mmap_read_evlist(rec, rec->evlist, false);
555 if (err)
556 return err;
557
558 return record__mmap_read_evlist(rec, rec->evlist, true);
559}
560
518static void record__init_features(struct record *rec) 561static void record__init_features(struct record *rec)
519{ 562{
520 struct perf_session *session = rec->session; 563 struct perf_session *session = rec->session;
@@ -561,13 +604,16 @@ record__finish_output(struct record *rec)
561 return; 604 return;
562} 605}
563 606
564static int record__synthesize_workload(struct record *rec) 607static int record__synthesize_workload(struct record *rec, bool tail)
565{ 608{
566 struct { 609 struct {
567 struct thread_map map; 610 struct thread_map map;
568 struct thread_map_data map_data; 611 struct thread_map_data map_data;
569 } thread_map; 612 } thread_map;
570 613
614 if (rec->opts.tail_synthesize != tail)
615 return 0;
616
571 thread_map.map.nr = 1; 617 thread_map.map.nr = 1;
572 thread_map.map.map[0].pid = rec->evlist->workload.pid; 618 thread_map.map.map[0].pid = rec->evlist->workload.pid;
573 thread_map.map.map[0].comm = NULL; 619 thread_map.map.map[0].comm = NULL;
@@ -578,7 +624,7 @@ static int record__synthesize_workload(struct record *rec)
578 rec->opts.proc_map_timeout); 624 rec->opts.proc_map_timeout);
579} 625}
580 626
581static int record__synthesize(struct record *rec); 627static int record__synthesize(struct record *rec, bool tail);
582 628
583static int 629static int
584record__switch_output(struct record *rec, bool at_exit) 630record__switch_output(struct record *rec, bool at_exit)
@@ -589,6 +635,10 @@ record__switch_output(struct record *rec, bool at_exit)
589 /* Same Size: "2015122520103046"*/ 635 /* Same Size: "2015122520103046"*/
590 char timestamp[] = "InvalidTimestamp"; 636 char timestamp[] = "InvalidTimestamp";
591 637
638 record__synthesize(rec, true);
639 if (target__none(&rec->opts.target))
640 record__synthesize_workload(rec, true);
641
592 rec->samples = 0; 642 rec->samples = 0;
593 record__finish_output(rec); 643 record__finish_output(rec);
594 err = fetch_current_timestamp(timestamp, sizeof(timestamp)); 644 err = fetch_current_timestamp(timestamp, sizeof(timestamp));
@@ -611,7 +661,7 @@ record__switch_output(struct record *rec, bool at_exit)
611 661
612 /* Output tracking events */ 662 /* Output tracking events */
613 if (!at_exit) { 663 if (!at_exit) {
614 record__synthesize(rec); 664 record__synthesize(rec, false);
615 665
616 /* 666 /*
617 * In 'perf record --switch-output' without -a, 667 * In 'perf record --switch-output' without -a,
@@ -623,7 +673,7 @@ record__switch_output(struct record *rec, bool at_exit)
623 * perf_event__synthesize_thread_map() for those events. 673 * perf_event__synthesize_thread_map() for those events.
624 */ 674 */
625 if (target__none(&rec->opts.target)) 675 if (target__none(&rec->opts.target))
626 record__synthesize_workload(rec); 676 record__synthesize_workload(rec, false);
627 } 677 }
628 return fd; 678 return fd;
629} 679}
@@ -655,7 +705,29 @@ perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused
655 return 0; 705 return 0;
656} 706}
657 707
658static int record__synthesize(struct record *rec) 708static const struct perf_event_mmap_page *
709perf_evlist__pick_pc(struct perf_evlist *evlist)
710{
711 if (evlist) {
712 if (evlist->mmap && evlist->mmap[0].base)
713 return evlist->mmap[0].base;
714 if (evlist->backward_mmap && evlist->backward_mmap[0].base)
715 return evlist->backward_mmap[0].base;
716 }
717 return NULL;
718}
719
720static const struct perf_event_mmap_page *record__pick_pc(struct record *rec)
721{
722 const struct perf_event_mmap_page *pc;
723
724 pc = perf_evlist__pick_pc(rec->evlist);
725 if (pc)
726 return pc;
727 return NULL;
728}
729
730static int record__synthesize(struct record *rec, bool tail)
659{ 731{
660 struct perf_session *session = rec->session; 732 struct perf_session *session = rec->session;
661 struct machine *machine = &session->machines.host; 733 struct machine *machine = &session->machines.host;
@@ -665,6 +737,9 @@ static int record__synthesize(struct record *rec)
665 int fd = perf_data_file__fd(file); 737 int fd = perf_data_file__fd(file);
666 int err = 0; 738 int err = 0;
667 739
740 if (rec->opts.tail_synthesize != tail)
741 return 0;
742
668 if (file->is_pipe) { 743 if (file->is_pipe) {
669 err = perf_event__synthesize_attrs(tool, session, 744 err = perf_event__synthesize_attrs(tool, session,
670 process_synthesized_event); 745 process_synthesized_event);
@@ -692,7 +767,7 @@ static int record__synthesize(struct record *rec)
692 } 767 }
693 } 768 }
694 769
695 err = perf_event__synth_time_conv(rec->evlist->mmap[0].base, tool, 770 err = perf_event__synth_time_conv(record__pick_pc(rec), tool,
696 process_synthesized_event, machine); 771 process_synthesized_event, machine);
697 if (err) 772 if (err)
698 goto out; 773 goto out;
@@ -828,7 +903,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
828 903
829 machine = &session->machines.host; 904 machine = &session->machines.host;
830 905
831 err = record__synthesize(rec); 906 err = record__synthesize(rec, false);
832 if (err < 0) 907 if (err < 0)
833 goto out_child; 908 goto out_child;
834 909
@@ -888,6 +963,17 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
888 for (;;) { 963 for (;;) {
889 unsigned long long hits = rec->samples; 964 unsigned long long hits = rec->samples;
890 965
966 /*
967 * rec->evlist->bkw_mmap_state is possible to be
968 * BKW_MMAP_EMPTY here: when done == true and
969 * hits != rec->samples in previous round.
970 *
971 * perf_evlist__toggle_bkw_mmap ensure we never
972 * convert BKW_MMAP_EMPTY to BKW_MMAP_DATA_PENDING.
973 */
974 if (trigger_is_hit(&switch_output_trigger) || done || draining)
975 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_DATA_PENDING);
976
891 if (record__mmap_read_all(rec) < 0) { 977 if (record__mmap_read_all(rec) < 0) {
892 trigger_error(&auxtrace_snapshot_trigger); 978 trigger_error(&auxtrace_snapshot_trigger);
893 trigger_error(&switch_output_trigger); 979 trigger_error(&switch_output_trigger);
@@ -907,8 +993,26 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
907 } 993 }
908 994
909 if (trigger_is_hit(&switch_output_trigger)) { 995 if (trigger_is_hit(&switch_output_trigger)) {
996 /*
997 * If switch_output_trigger is hit, the data in
998 * overwritable ring buffer should have been collected,
999 * so bkw_mmap_state should be set to BKW_MMAP_EMPTY.
1000 *
1001 * If SIGUSR2 raise after or during record__mmap_read_all(),
1002 * record__mmap_read_all() didn't collect data from
1003 * overwritable ring buffer. Read again.
1004 */
1005 if (rec->evlist->bkw_mmap_state == BKW_MMAP_RUNNING)
1006 continue;
910 trigger_ready(&switch_output_trigger); 1007 trigger_ready(&switch_output_trigger);
911 1008
1009 /*
1010 * Reenable events in overwrite ring buffer after
1011 * record__mmap_read_all(): we should have collected
1012 * data from it.
1013 */
1014 perf_evlist__toggle_bkw_mmap(rec->evlist, BKW_MMAP_RUNNING);
1015
912 if (!quiet) 1016 if (!quiet)
913 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n", 1017 fprintf(stderr, "[ perf record: dump data: Woken up %ld times ]\n",
914 waking); 1018 waking);
@@ -954,7 +1058,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
954 1058
955 if (forks && workload_exec_errno) { 1059 if (forks && workload_exec_errno) {
956 char msg[STRERR_BUFSIZE]; 1060 char msg[STRERR_BUFSIZE];
957 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); 1061 const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
958 pr_err("Workload failed: %s\n", emsg); 1062 pr_err("Workload failed: %s\n", emsg);
959 err = -1; 1063 err = -1;
960 goto out_child; 1064 goto out_child;
@@ -963,6 +1067,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
963 if (!quiet) 1067 if (!quiet)
964 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); 1068 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
965 1069
1070 if (target__none(&rec->opts.target))
1071 record__synthesize_workload(rec, true);
1072
966out_child: 1073out_child:
967 if (forks) { 1074 if (forks) {
968 int exit_status; 1075 int exit_status;
@@ -981,6 +1088,7 @@ out_child:
981 } else 1088 } else
982 status = err; 1089 status = err;
983 1090
1091 record__synthesize(rec, true);
984 /* this will be recalculated during process_buildids() */ 1092 /* this will be recalculated during process_buildids() */
985 rec->samples = 0; 1093 rec->samples = 0;
986 1094
@@ -1267,6 +1375,8 @@ static struct record record = {
1267const char record_callchain_help[] = CALLCHAIN_RECORD_HELP 1375const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
1268 "\n\t\t\t\tDefault: fp"; 1376 "\n\t\t\t\tDefault: fp";
1269 1377
1378static bool dry_run;
1379
1270/* 1380/*
1271 * XXX Will stay a global variable till we fix builtin-script.c to stop messing 1381 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
1272 * with it and switch to use the library functions in perf_evlist that came 1382 * with it and switch to use the library functions in perf_evlist that came
@@ -1303,6 +1413,9 @@ struct option __record_options[] = {
1303 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, 1413 OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit,
1304 &record.opts.no_inherit_set, 1414 &record.opts.no_inherit_set,
1305 "child tasks do not inherit counters"), 1415 "child tasks do not inherit counters"),
1416 OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
1417 "synthesize non-sample events at the end of output"),
1418 OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
1306 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"), 1419 OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
1307 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]", 1420 OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
1308 "number of mmap data pages and AUX area tracing mmap pages", 1421 "number of mmap data pages and AUX area tracing mmap pages",
@@ -1386,6 +1499,8 @@ struct option __record_options[] = {
1386 "append timestamp to output filename"), 1499 "append timestamp to output filename"),
1387 OPT_BOOLEAN(0, "switch-output", &record.switch_output, 1500 OPT_BOOLEAN(0, "switch-output", &record.switch_output,
1388 "Switch output when receive SIGUSR2"), 1501 "Switch output when receive SIGUSR2"),
1502 OPT_BOOLEAN(0, "dry-run", &dry_run,
1503 "Parse options then exit"),
1389 OPT_END() 1504 OPT_END()
1390}; 1505};
1391 1506
@@ -1455,6 +1570,9 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1455 if (err) 1570 if (err)
1456 return err; 1571 return err;
1457 1572
1573 if (dry_run)
1574 return 0;
1575
1458 err = bpf__setup_stdout(rec->evlist); 1576 err = bpf__setup_stdout(rec->evlist);
1459 if (err) { 1577 if (err) {
1460 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf)); 1578 bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
@@ -1508,6 +1626,9 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1508 } 1626 }
1509 } 1627 }
1510 1628
1629 if (record.opts.overwrite)
1630 record.opts.tail_synthesize = true;
1631
1511 if (rec->evlist->nr_entries == 0 && 1632 if (rec->evlist->nr_entries == 0 &&
1512 perf_evlist__add_default(rec->evlist) < 0) { 1633 perf_evlist__add_default(rec->evlist) < 0) {
1513 pr_err("Not enough memory for event selector list\n"); 1634 pr_err("Not enough memory for event selector list\n");
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index a87cb338bdf1..949e5a15c960 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -8,7 +8,7 @@
8#include "builtin.h" 8#include "builtin.h"
9 9
10#include "util/util.h" 10#include "util/util.h"
11#include "util/cache.h" 11#include "util/config.h"
12 12
13#include "util/annotate.h" 13#include "util/annotate.h"
14#include "util/color.h" 14#include "util/color.h"
@@ -361,7 +361,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
361 struct perf_evsel *pos; 361 struct perf_evsel *pos;
362 362
363 fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", evlist->stats.total_lost_samples); 363 fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", evlist->stats.total_lost_samples);
364 evlist__for_each(evlist, pos) { 364 evlist__for_each_entry(evlist, pos) {
365 struct hists *hists = evsel__hists(pos); 365 struct hists *hists = evsel__hists(pos);
366 const char *evname = perf_evsel__name(pos); 366 const char *evname = perf_evsel__name(pos);
367 367
@@ -370,7 +370,8 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
370 continue; 370 continue;
371 371
372 hists__fprintf_nr_sample_events(hists, rep, evname, stdout); 372 hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
373 hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout); 373 hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout,
374 symbol_conf.use_callchain);
374 fprintf(stdout, "\n\n"); 375 fprintf(stdout, "\n\n");
375 } 376 }
376 377
@@ -477,7 +478,7 @@ static int report__collapse_hists(struct report *rep)
477 478
478 ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); 479 ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
479 480
480 evlist__for_each(rep->session->evlist, pos) { 481 evlist__for_each_entry(rep->session->evlist, pos) {
481 struct hists *hists = evsel__hists(pos); 482 struct hists *hists = evsel__hists(pos);
482 483
483 if (pos->idx == 0) 484 if (pos->idx == 0)
@@ -510,7 +511,7 @@ static void report__output_resort(struct report *rep)
510 511
511 ui_progress__init(&prog, rep->nr_entries, "Sorting events for output..."); 512 ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");
512 513
513 evlist__for_each(rep->session->evlist, pos) 514 evlist__for_each_entry(rep->session->evlist, pos)
514 perf_evsel__output_resort(pos, &prog); 515 perf_evsel__output_resort(pos, &prog);
515 516
516 ui_progress__finish(); 517 ui_progress__finish();
@@ -551,7 +552,7 @@ static int __cmd_report(struct report *rep)
551 552
552 report__warn_kptr_restrict(rep); 553 report__warn_kptr_restrict(rep);
553 554
554 evlist__for_each(session->evlist, pos) 555 evlist__for_each_entry(session->evlist, pos)
555 rep->nr_entries += evsel__hists(pos)->nr_entries; 556 rep->nr_entries += evsel__hists(pos)->nr_entries;
556 557
557 if (use_browser == 0) { 558 if (use_browser == 0) {
@@ -582,7 +583,7 @@ static int __cmd_report(struct report *rep)
582 * might be changed during the collapse phase. 583 * might be changed during the collapse phase.
583 */ 584 */
584 rep->nr_entries = 0; 585 rep->nr_entries = 0;
585 evlist__for_each(session->evlist, pos) 586 evlist__for_each_entry(session->evlist, pos)
586 rep->nr_entries += evsel__hists(pos)->nr_entries; 587 rep->nr_entries += evsel__hists(pos)->nr_entries;
587 588
588 if (rep->nr_entries == 0) { 589 if (rep->nr_entries == 0) {
@@ -816,6 +817,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
816 "Show raw trace event output (do not use print fmt or plugins)"), 817 "Show raw trace event output (do not use print fmt or plugins)"),
817 OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy, 818 OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy,
818 "Show entries in a hierarchy"), 819 "Show entries in a hierarchy"),
820 OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
821 "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
822 stdio__config_color, "always"),
819 OPT_END() 823 OPT_END()
820 }; 824 };
821 struct perf_data_file file = { 825 struct perf_data_file file = {
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index afa057666c2a..0dfe8df2ab9b 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -494,7 +494,7 @@ force_again:
494 } 494 }
495 pr_err("Error: sys_perf_event_open() syscall returned " 495 pr_err("Error: sys_perf_event_open() syscall returned "
496 "with %d (%s)\n%s", fd, 496 "with %d (%s)\n%s", fd,
497 strerror_r(errno, sbuf, sizeof(sbuf)), info); 497 str_error_r(errno, sbuf, sizeof(sbuf)), info);
498 exit(EXIT_FAILURE); 498 exit(EXIT_FAILURE);
499 } 499 }
500 return fd; 500 return fd;
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index e3ce2f34d3ad..971ff91b16cb 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -21,6 +21,7 @@
21#include "util/cpumap.h" 21#include "util/cpumap.h"
22#include "util/thread_map.h" 22#include "util/thread_map.h"
23#include "util/stat.h" 23#include "util/stat.h"
24#include "util/thread-stack.h"
24#include <linux/bitmap.h> 25#include <linux/bitmap.h>
25#include <linux/stringify.h> 26#include <linux/stringify.h>
26#include "asm/bug.h" 27#include "asm/bug.h"
@@ -63,6 +64,7 @@ enum perf_output_field {
63 PERF_OUTPUT_DATA_SRC = 1U << 17, 64 PERF_OUTPUT_DATA_SRC = 1U << 17,
64 PERF_OUTPUT_WEIGHT = 1U << 18, 65 PERF_OUTPUT_WEIGHT = 1U << 18,
65 PERF_OUTPUT_BPF_OUTPUT = 1U << 19, 66 PERF_OUTPUT_BPF_OUTPUT = 1U << 19,
67 PERF_OUTPUT_CALLINDENT = 1U << 20,
66}; 68};
67 69
68struct output_option { 70struct output_option {
@@ -89,6 +91,7 @@ struct output_option {
89 {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC}, 91 {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC},
90 {.str = "weight", .field = PERF_OUTPUT_WEIGHT}, 92 {.str = "weight", .field = PERF_OUTPUT_WEIGHT},
91 {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT}, 93 {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT},
94 {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT},
92}; 95};
93 96
94/* default set to maintain compatibility with current format */ 97/* default set to maintain compatibility with current format */
@@ -339,7 +342,7 @@ static void set_print_ip_opts(struct perf_event_attr *attr)
339 */ 342 */
340static int perf_session__check_output_opt(struct perf_session *session) 343static int perf_session__check_output_opt(struct perf_session *session)
341{ 344{
342 int j; 345 unsigned int j;
343 struct perf_evsel *evsel; 346 struct perf_evsel *evsel;
344 347
345 for (j = 0; j < PERF_TYPE_MAX; ++j) { 348 for (j = 0; j < PERF_TYPE_MAX; ++j) {
@@ -369,7 +372,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
369 if (!no_callchain) { 372 if (!no_callchain) {
370 bool use_callchain = false; 373 bool use_callchain = false;
371 374
372 evlist__for_each(session->evlist, evsel) { 375 evlist__for_each_entry(session->evlist, evsel) {
373 if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { 376 if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
374 use_callchain = true; 377 use_callchain = true;
375 break; 378 break;
@@ -388,17 +391,20 @@ static int perf_session__check_output_opt(struct perf_session *session)
388 struct perf_event_attr *attr; 391 struct perf_event_attr *attr;
389 392
390 j = PERF_TYPE_TRACEPOINT; 393 j = PERF_TYPE_TRACEPOINT;
391 evsel = perf_session__find_first_evtype(session, j);
392 if (evsel == NULL)
393 goto out;
394 394
395 attr = &evsel->attr; 395 evlist__for_each_entry(session->evlist, evsel) {
396 if (evsel->attr.type != j)
397 continue;
398
399 attr = &evsel->attr;
396 400
397 if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) { 401 if (attr->sample_type & PERF_SAMPLE_CALLCHAIN) {
398 output[j].fields |= PERF_OUTPUT_IP; 402 output[j].fields |= PERF_OUTPUT_IP;
399 output[j].fields |= PERF_OUTPUT_SYM; 403 output[j].fields |= PERF_OUTPUT_SYM;
400 output[j].fields |= PERF_OUTPUT_DSO; 404 output[j].fields |= PERF_OUTPUT_DSO;
401 set_print_ip_opts(attr); 405 set_print_ip_opts(attr);
406 goto out;
407 }
402 } 408 }
403 } 409 }
404 410
@@ -559,6 +565,62 @@ static void print_sample_addr(struct perf_sample *sample,
559 } 565 }
560} 566}
561 567
568static void print_sample_callindent(struct perf_sample *sample,
569 struct perf_evsel *evsel,
570 struct thread *thread,
571 struct addr_location *al)
572{
573 struct perf_event_attr *attr = &evsel->attr;
574 size_t depth = thread_stack__depth(thread);
575 struct addr_location addr_al;
576 const char *name = NULL;
577 static int spacing;
578 int len = 0;
579 u64 ip = 0;
580
581 /*
582 * The 'return' has already been popped off the stack so the depth has
583 * to be adjusted to match the 'call'.
584 */
585 if (thread->ts && sample->flags & PERF_IP_FLAG_RETURN)
586 depth += 1;
587
588 if (sample->flags & (PERF_IP_FLAG_CALL | PERF_IP_FLAG_TRACE_BEGIN)) {
589 if (sample_addr_correlates_sym(attr)) {
590 thread__resolve(thread, &addr_al, sample);
591 if (addr_al.sym)
592 name = addr_al.sym->name;
593 else
594 ip = sample->addr;
595 } else {
596 ip = sample->addr;
597 }
598 } else if (sample->flags & (PERF_IP_FLAG_RETURN | PERF_IP_FLAG_TRACE_END)) {
599 if (al->sym)
600 name = al->sym->name;
601 else
602 ip = sample->ip;
603 }
604
605 if (name)
606 len = printf("%*s%s", (int)depth * 4, "", name);
607 else if (ip)
608 len = printf("%*s%16" PRIx64, (int)depth * 4, "", ip);
609
610 if (len < 0)
611 return;
612
613 /*
614 * Try to keep the output length from changing frequently so that the
615 * output lines up more nicely.
616 */
617 if (len > spacing || (len && len < spacing - 52))
618 spacing = round_up(len + 4, 32);
619
620 if (len < spacing)
621 printf("%*s", spacing - len, "");
622}
623
562static void print_sample_bts(struct perf_sample *sample, 624static void print_sample_bts(struct perf_sample *sample,
563 struct perf_evsel *evsel, 625 struct perf_evsel *evsel,
564 struct thread *thread, 626 struct thread *thread,
@@ -567,6 +629,9 @@ static void print_sample_bts(struct perf_sample *sample,
567 struct perf_event_attr *attr = &evsel->attr; 629 struct perf_event_attr *attr = &evsel->attr;
568 bool print_srcline_last = false; 630 bool print_srcline_last = false;
569 631
632 if (PRINT_FIELD(CALLINDENT))
633 print_sample_callindent(sample, evsel, thread, al);
634
570 /* print branch_from information */ 635 /* print branch_from information */
571 if (PRINT_FIELD(IP)) { 636 if (PRINT_FIELD(IP)) {
572 unsigned int print_opts = output[attr->type].print_ip_opts; 637 unsigned int print_opts = output[attr->type].print_ip_opts;
@@ -603,13 +668,42 @@ static void print_sample_bts(struct perf_sample *sample,
603 printf("\n"); 668 printf("\n");
604} 669}
605 670
671static struct {
672 u32 flags;
673 const char *name;
674} sample_flags[] = {
675 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL, "call"},
676 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN, "return"},
677 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CONDITIONAL, "jcc"},
678 {PERF_IP_FLAG_BRANCH, "jmp"},
679 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT, "int"},
680 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT, "iret"},
681 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_SYSCALLRET, "syscall"},
682 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_SYSCALLRET, "sysret"},
683 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_ASYNC, "async"},
684 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRUPT, "hw int"},
685 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT, "tx abrt"},
686 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_BEGIN, "tr strt"},
687 {PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END, "tr end"},
688 {0, NULL}
689};
690
606static void print_sample_flags(u32 flags) 691static void print_sample_flags(u32 flags)
607{ 692{
608 const char *chars = PERF_IP_FLAG_CHARS; 693 const char *chars = PERF_IP_FLAG_CHARS;
609 const int n = strlen(PERF_IP_FLAG_CHARS); 694 const int n = strlen(PERF_IP_FLAG_CHARS);
695 bool in_tx = flags & PERF_IP_FLAG_IN_TX;
696 const char *name = NULL;
610 char str[33]; 697 char str[33];
611 int i, pos = 0; 698 int i, pos = 0;
612 699
700 for (i = 0; sample_flags[i].name ; i++) {
701 if (sample_flags[i].flags == (flags & ~PERF_IP_FLAG_IN_TX)) {
702 name = sample_flags[i].name;
703 break;
704 }
705 }
706
613 for (i = 0; i < n; i++, flags >>= 1) { 707 for (i = 0; i < n; i++, flags >>= 1) {
614 if (flags & 1) 708 if (flags & 1)
615 str[pos++] = chars[i]; 709 str[pos++] = chars[i];
@@ -619,7 +713,11 @@ static void print_sample_flags(u32 flags)
619 str[pos++] = '?'; 713 str[pos++] = '?';
620 } 714 }
621 str[pos] = 0; 715 str[pos] = 0;
622 printf(" %-4s ", str); 716
717 if (name)
718 printf(" %-7s%4s ", name, in_tx ? "(x)" : "");
719 else
720 printf(" %-11s ", str);
623} 721}
624 722
625struct printer_data { 723struct printer_data {
@@ -717,7 +815,7 @@ static int perf_evlist__max_name_len(struct perf_evlist *evlist)
717 struct perf_evsel *evsel; 815 struct perf_evsel *evsel;
718 int max = 0; 816 int max = 0;
719 817
720 evlist__for_each(evlist, evsel) { 818 evlist__for_each_entry(evlist, evsel) {
721 int len = strlen(perf_evsel__name(evsel)); 819 int len = strlen(perf_evsel__name(evsel));
722 820
723 max = MAX(len, max); 821 max = MAX(len, max);
@@ -942,7 +1040,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
942 if (evsel->attr.type >= PERF_TYPE_MAX) 1040 if (evsel->attr.type >= PERF_TYPE_MAX)
943 return 0; 1041 return 0;
944 1042
945 evlist__for_each(evlist, pos) { 1043 evlist__for_each_entry(evlist, pos) {
946 if (pos->attr.type == evsel->attr.type && pos != evsel) 1044 if (pos->attr.type == evsel->attr.type && pos != evsel)
947 return 0; 1045 return 0;
948 } 1046 }
@@ -1668,7 +1766,7 @@ static int check_ev_match(char *dir_name, char *scriptname,
1668 snprintf(evname, len + 1, "%s", p); 1766 snprintf(evname, len + 1, "%s", p);
1669 1767
1670 match = 0; 1768 match = 0;
1671 evlist__for_each(session->evlist, pos) { 1769 evlist__for_each_entry(session->evlist, pos) {
1672 if (!strcmp(perf_evsel__name(pos), evname)) { 1770 if (!strcmp(perf_evsel__name(pos), evname)) {
1673 match = 1; 1771 match = 1;
1674 break; 1772 break;
@@ -1870,7 +1968,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
1870 struct stat_round_event *round = &event->stat_round; 1968 struct stat_round_event *round = &event->stat_round;
1871 struct perf_evsel *counter; 1969 struct perf_evsel *counter;
1872 1970
1873 evlist__for_each(session->evlist, counter) { 1971 evlist__for_each_entry(session->evlist, counter) {
1874 perf_stat_process_counter(&stat_config, counter); 1972 perf_stat_process_counter(&stat_config, counter);
1875 process_stat(counter, round->time); 1973 process_stat(counter, round->time);
1876 } 1974 }
@@ -2017,7 +2115,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
2017 "comma separated output fields prepend with 'type:'. " 2115 "comma separated output fields prepend with 'type:'. "
2018 "Valid types: hw,sw,trace,raw. " 2116 "Valid types: hw,sw,trace,raw. "
2019 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 2117 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
2020 "addr,symoff,period,iregs,brstack,brstacksym,flags", parse_output_fields), 2118 "addr,symoff,period,iregs,brstack,brstacksym,flags,"
2119 "callindent", parse_output_fields),
2021 OPT_BOOLEAN('a', "all-cpus", &system_wide, 2120 OPT_BOOLEAN('a', "all-cpus", &system_wide,
2022 "system-wide collection from all CPUs"), 2121 "system-wide collection from all CPUs"),
2023 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 2122 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
@@ -2256,6 +2355,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
2256 script.session = session; 2355 script.session = session;
2257 script__setup_sample_type(&script); 2356 script__setup_sample_type(&script);
2258 2357
2358 if (output[PERF_TYPE_HARDWARE].fields & PERF_OUTPUT_CALLINDENT)
2359 itrace_synth_opts.thread_stack = true;
2360
2259 session->itrace_synth_opts = &itrace_synth_opts; 2361 session->itrace_synth_opts = &itrace_synth_opts;
2260 2362
2261 if (cpu_list) { 2363 if (cpu_list) {
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ee7ada78d86f..0c16d20d7e32 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -59,10 +59,13 @@
59#include "util/thread.h" 59#include "util/thread.h"
60#include "util/thread_map.h" 60#include "util/thread_map.h"
61#include "util/counts.h" 61#include "util/counts.h"
62#include "util/group.h"
62#include "util/session.h" 63#include "util/session.h"
63#include "util/tool.h" 64#include "util/tool.h"
65#include "util/group.h"
64#include "asm/bug.h" 66#include "asm/bug.h"
65 67
68#include <api/fs/fs.h>
66#include <stdlib.h> 69#include <stdlib.h>
67#include <sys/prctl.h> 70#include <sys/prctl.h>
68#include <locale.h> 71#include <locale.h>
@@ -98,6 +101,15 @@ static const char * transaction_limited_attrs = {
98 "}" 101 "}"
99}; 102};
100 103
104static const char * topdown_attrs[] = {
105 "topdown-total-slots",
106 "topdown-slots-retired",
107 "topdown-recovery-bubbles",
108 "topdown-fetch-bubbles",
109 "topdown-slots-issued",
110 NULL,
111};
112
101static struct perf_evlist *evsel_list; 113static struct perf_evlist *evsel_list;
102 114
103static struct target target = { 115static struct target target = {
@@ -112,6 +124,7 @@ static volatile pid_t child_pid = -1;
112static bool null_run = false; 124static bool null_run = false;
113static int detailed_run = 0; 125static int detailed_run = 0;
114static bool transaction_run; 126static bool transaction_run;
127static bool topdown_run = false;
115static bool big_num = true; 128static bool big_num = true;
116static int big_num_opt = -1; 129static int big_num_opt = -1;
117static const char *csv_sep = NULL; 130static const char *csv_sep = NULL;
@@ -124,6 +137,7 @@ static unsigned int initial_delay = 0;
124static unsigned int unit_width = 4; /* strlen("unit") */ 137static unsigned int unit_width = 4; /* strlen("unit") */
125static bool forever = false; 138static bool forever = false;
126static bool metric_only = false; 139static bool metric_only = false;
140static bool force_metric_only = false;
127static struct timespec ref_time; 141static struct timespec ref_time;
128static struct cpu_map *aggr_map; 142static struct cpu_map *aggr_map;
129static aggr_get_id_t aggr_get_id; 143static aggr_get_id_t aggr_get_id;
@@ -276,8 +290,12 @@ perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread,
276static int read_counter(struct perf_evsel *counter) 290static int read_counter(struct perf_evsel *counter)
277{ 291{
278 int nthreads = thread_map__nr(evsel_list->threads); 292 int nthreads = thread_map__nr(evsel_list->threads);
279 int ncpus = perf_evsel__nr_cpus(counter); 293 int ncpus, cpu, thread;
280 int cpu, thread; 294
295 if (target__has_cpu(&target))
296 ncpus = perf_evsel__nr_cpus(counter);
297 else
298 ncpus = 1;
281 299
282 if (!counter->supported) 300 if (!counter->supported)
283 return -ENOENT; 301 return -ENOENT;
@@ -317,7 +335,7 @@ static void read_counters(bool close_counters)
317{ 335{
318 struct perf_evsel *counter; 336 struct perf_evsel *counter;
319 337
320 evlist__for_each(evsel_list, counter) { 338 evlist__for_each_entry(evsel_list, counter) {
321 if (read_counter(counter)) 339 if (read_counter(counter))
322 pr_debug("failed to read counter %s\n", counter->name); 340 pr_debug("failed to read counter %s\n", counter->name);
323 341
@@ -403,7 +421,7 @@ static int perf_stat_synthesize_config(bool is_pipe)
403 * Synthesize other events stuff not carried within 421 * Synthesize other events stuff not carried within
404 * attr event - unit, scale, name 422 * attr event - unit, scale, name
405 */ 423 */
406 evlist__for_each(evsel_list, counter) { 424 evlist__for_each_entry(evsel_list, counter) {
407 if (!counter->supported) 425 if (!counter->supported)
408 continue; 426 continue;
409 427
@@ -536,7 +554,7 @@ static int __run_perf_stat(int argc, const char **argv)
536 if (group) 554 if (group)
537 perf_evlist__set_leader(evsel_list); 555 perf_evlist__set_leader(evsel_list);
538 556
539 evlist__for_each(evsel_list, counter) { 557 evlist__for_each_entry(evsel_list, counter) {
540try_again: 558try_again:
541 if (create_perf_stat_counter(counter) < 0) { 559 if (create_perf_stat_counter(counter) < 0) {
542 /* 560 /*
@@ -582,7 +600,7 @@ try_again:
582 if (perf_evlist__apply_filters(evsel_list, &counter)) { 600 if (perf_evlist__apply_filters(evsel_list, &counter)) {
583 error("failed to set filter \"%s\" on event %s with %d (%s)\n", 601 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
584 counter->filter, perf_evsel__name(counter), errno, 602 counter->filter, perf_evsel__name(counter), errno,
585 strerror_r(errno, msg, sizeof(msg))); 603 str_error_r(errno, msg, sizeof(msg)));
586 return -1; 604 return -1;
587 } 605 }
588 606
@@ -623,7 +641,7 @@ try_again:
623 wait(&status); 641 wait(&status);
624 642
625 if (workload_exec_errno) { 643 if (workload_exec_errno) {
626 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); 644 const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
627 pr_err("Workload failed: %s\n", emsg); 645 pr_err("Workload failed: %s\n", emsg);
628 return -1; 646 return -1;
629 } 647 }
@@ -1120,7 +1138,7 @@ static void aggr_update_shadow(void)
1120 1138
1121 for (s = 0; s < aggr_map->nr; s++) { 1139 for (s = 0; s < aggr_map->nr; s++) {
1122 id = aggr_map->map[s]; 1140 id = aggr_map->map[s];
1123 evlist__for_each(evsel_list, counter) { 1141 evlist__for_each_entry(evsel_list, counter) {
1124 val = 0; 1142 val = 0;
1125 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 1143 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1126 s2 = aggr_get_id(evsel_list->cpus, cpu); 1144 s2 = aggr_get_id(evsel_list->cpus, cpu);
@@ -1159,7 +1177,7 @@ static void print_aggr(char *prefix)
1159 1177
1160 id = aggr_map->map[s]; 1178 id = aggr_map->map[s];
1161 first = true; 1179 first = true;
1162 evlist__for_each(evsel_list, counter) { 1180 evlist__for_each_entry(evsel_list, counter) {
1163 val = ena = run = 0; 1181 val = ena = run = 0;
1164 nr = 0; 1182 nr = 0;
1165 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 1183 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
@@ -1278,7 +1296,7 @@ static void print_no_aggr_metric(char *prefix)
1278 1296
1279 if (prefix) 1297 if (prefix)
1280 fputs(prefix, stat_config.output); 1298 fputs(prefix, stat_config.output);
1281 evlist__for_each(evsel_list, counter) { 1299 evlist__for_each_entry(evsel_list, counter) {
1282 if (first) { 1300 if (first) {
1283 aggr_printout(counter, cpu, 0); 1301 aggr_printout(counter, cpu, 0);
1284 first = false; 1302 first = false;
@@ -1302,7 +1320,15 @@ static int aggr_header_lens[] = {
1302 [AGGR_GLOBAL] = 0, 1320 [AGGR_GLOBAL] = 0,
1303}; 1321};
1304 1322
1305static void print_metric_headers(char *prefix) 1323static const char *aggr_header_csv[] = {
1324 [AGGR_CORE] = "core,cpus,",
1325 [AGGR_SOCKET] = "socket,cpus",
1326 [AGGR_NONE] = "cpu,",
1327 [AGGR_THREAD] = "comm-pid,",
1328 [AGGR_GLOBAL] = ""
1329};
1330
1331static void print_metric_headers(const char *prefix, bool no_indent)
1306{ 1332{
1307 struct perf_stat_output_ctx out; 1333 struct perf_stat_output_ctx out;
1308 struct perf_evsel *counter; 1334 struct perf_evsel *counter;
@@ -1313,12 +1339,18 @@ static void print_metric_headers(char *prefix)
1313 if (prefix) 1339 if (prefix)
1314 fprintf(stat_config.output, "%s", prefix); 1340 fprintf(stat_config.output, "%s", prefix);
1315 1341
1316 if (!csv_output) 1342 if (!csv_output && !no_indent)
1317 fprintf(stat_config.output, "%*s", 1343 fprintf(stat_config.output, "%*s",
1318 aggr_header_lens[stat_config.aggr_mode], ""); 1344 aggr_header_lens[stat_config.aggr_mode], "");
1345 if (csv_output) {
1346 if (stat_config.interval)
1347 fputs("time,", stat_config.output);
1348 fputs(aggr_header_csv[stat_config.aggr_mode],
1349 stat_config.output);
1350 }
1319 1351
1320 /* Print metrics headers only */ 1352 /* Print metrics headers only */
1321 evlist__for_each(evsel_list, counter) { 1353 evlist__for_each_entry(evsel_list, counter) {
1322 os.evsel = counter; 1354 os.evsel = counter;
1323 out.ctx = &os; 1355 out.ctx = &os;
1324 out.print_metric = print_metric_header; 1356 out.print_metric = print_metric_header;
@@ -1338,28 +1370,40 @@ static void print_interval(char *prefix, struct timespec *ts)
1338 1370
1339 sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep); 1371 sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
1340 1372
1341 if (num_print_interval == 0 && !csv_output && !metric_only) { 1373 if (num_print_interval == 0 && !csv_output) {
1342 switch (stat_config.aggr_mode) { 1374 switch (stat_config.aggr_mode) {
1343 case AGGR_SOCKET: 1375 case AGGR_SOCKET:
1344 fprintf(output, "# time socket cpus counts %*s events\n", unit_width, "unit"); 1376 fprintf(output, "# time socket cpus");
1377 if (!metric_only)
1378 fprintf(output, " counts %*s events\n", unit_width, "unit");
1345 break; 1379 break;
1346 case AGGR_CORE: 1380 case AGGR_CORE:
1347 fprintf(output, "# time core cpus counts %*s events\n", unit_width, "unit"); 1381 fprintf(output, "# time core cpus");
1382 if (!metric_only)
1383 fprintf(output, " counts %*s events\n", unit_width, "unit");
1348 break; 1384 break;
1349 case AGGR_NONE: 1385 case AGGR_NONE:
1350 fprintf(output, "# time CPU counts %*s events\n", unit_width, "unit"); 1386 fprintf(output, "# time CPU");
1387 if (!metric_only)
1388 fprintf(output, " counts %*s events\n", unit_width, "unit");
1351 break; 1389 break;
1352 case AGGR_THREAD: 1390 case AGGR_THREAD:
1353 fprintf(output, "# time comm-pid counts %*s events\n", unit_width, "unit"); 1391 fprintf(output, "# time comm-pid");
1392 if (!metric_only)
1393 fprintf(output, " counts %*s events\n", unit_width, "unit");
1354 break; 1394 break;
1355 case AGGR_GLOBAL: 1395 case AGGR_GLOBAL:
1356 default: 1396 default:
1357 fprintf(output, "# time counts %*s events\n", unit_width, "unit"); 1397 fprintf(output, "# time");
1398 if (!metric_only)
1399 fprintf(output, " counts %*s events\n", unit_width, "unit");
1358 case AGGR_UNSET: 1400 case AGGR_UNSET:
1359 break; 1401 break;
1360 } 1402 }
1361 } 1403 }
1362 1404
1405 if (num_print_interval == 0 && metric_only)
1406 print_metric_headers(" ", true);
1363 if (++num_print_interval == 25) 1407 if (++num_print_interval == 25)
1364 num_print_interval = 0; 1408 num_print_interval = 0;
1365} 1409}
@@ -1428,8 +1472,8 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
1428 if (metric_only) { 1472 if (metric_only) {
1429 static int num_print_iv; 1473 static int num_print_iv;
1430 1474
1431 if (num_print_iv == 0) 1475 if (num_print_iv == 0 && !interval)
1432 print_metric_headers(prefix); 1476 print_metric_headers(prefix, false);
1433 if (num_print_iv++ == 25) 1477 if (num_print_iv++ == 25)
1434 num_print_iv = 0; 1478 num_print_iv = 0;
1435 if (stat_config.aggr_mode == AGGR_GLOBAL && prefix) 1479 if (stat_config.aggr_mode == AGGR_GLOBAL && prefix)
@@ -1442,11 +1486,11 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
1442 print_aggr(prefix); 1486 print_aggr(prefix);
1443 break; 1487 break;
1444 case AGGR_THREAD: 1488 case AGGR_THREAD:
1445 evlist__for_each(evsel_list, counter) 1489 evlist__for_each_entry(evsel_list, counter)
1446 print_aggr_thread(counter, prefix); 1490 print_aggr_thread(counter, prefix);
1447 break; 1491 break;
1448 case AGGR_GLOBAL: 1492 case AGGR_GLOBAL:
1449 evlist__for_each(evsel_list, counter) 1493 evlist__for_each_entry(evsel_list, counter)
1450 print_counter_aggr(counter, prefix); 1494 print_counter_aggr(counter, prefix);
1451 if (metric_only) 1495 if (metric_only)
1452 fputc('\n', stat_config.output); 1496 fputc('\n', stat_config.output);
@@ -1455,7 +1499,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
1455 if (metric_only) 1499 if (metric_only)
1456 print_no_aggr_metric(prefix); 1500 print_no_aggr_metric(prefix);
1457 else { 1501 else {
1458 evlist__for_each(evsel_list, counter) 1502 evlist__for_each_entry(evsel_list, counter)
1459 print_counter(counter, prefix); 1503 print_counter(counter, prefix);
1460 } 1504 }
1461 break; 1505 break;
@@ -1520,6 +1564,14 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,
1520 return 0; 1564 return 0;
1521} 1565}
1522 1566
1567static int enable_metric_only(const struct option *opt __maybe_unused,
1568 const char *s __maybe_unused, int unset)
1569{
1570 force_metric_only = true;
1571 metric_only = !unset;
1572 return 0;
1573}
1574
1523static const struct option stat_options[] = { 1575static const struct option stat_options[] = {
1524 OPT_BOOLEAN('T', "transaction", &transaction_run, 1576 OPT_BOOLEAN('T', "transaction", &transaction_run,
1525 "hardware transaction statistics"), 1577 "hardware transaction statistics"),
@@ -1578,8 +1630,10 @@ static const struct option stat_options[] = {
1578 "aggregate counts per thread", AGGR_THREAD), 1630 "aggregate counts per thread", AGGR_THREAD),
1579 OPT_UINTEGER('D', "delay", &initial_delay, 1631 OPT_UINTEGER('D', "delay", &initial_delay,
1580 "ms to wait before starting measurement after program start"), 1632 "ms to wait before starting measurement after program start"),
1581 OPT_BOOLEAN(0, "metric-only", &metric_only, 1633 OPT_CALLBACK_NOOPT(0, "metric-only", &metric_only, NULL,
1582 "Only print computed metrics. No raw values"), 1634 "Only print computed metrics. No raw values", enable_metric_only),
1635 OPT_BOOLEAN(0, "topdown", &topdown_run,
1636 "measure topdown level 1 statistics"),
1583 OPT_END() 1637 OPT_END()
1584}; 1638};
1585 1639
@@ -1772,12 +1826,62 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
1772 return 0; 1826 return 0;
1773} 1827}
1774 1828
1829static int topdown_filter_events(const char **attr, char **str, bool use_group)
1830{
1831 int off = 0;
1832 int i;
1833 int len = 0;
1834 char *s;
1835
1836 for (i = 0; attr[i]; i++) {
1837 if (pmu_have_event("cpu", attr[i])) {
1838 len += strlen(attr[i]) + 1;
1839 attr[i - off] = attr[i];
1840 } else
1841 off++;
1842 }
1843 attr[i - off] = NULL;
1844
1845 *str = malloc(len + 1 + 2);
1846 if (!*str)
1847 return -1;
1848 s = *str;
1849 if (i - off == 0) {
1850 *s = 0;
1851 return 0;
1852 }
1853 if (use_group)
1854 *s++ = '{';
1855 for (i = 0; attr[i]; i++) {
1856 strcpy(s, attr[i]);
1857 s += strlen(s);
1858 *s++ = ',';
1859 }
1860 if (use_group) {
1861 s[-1] = '}';
1862 *s = 0;
1863 } else
1864 s[-1] = 0;
1865 return 0;
1866}
1867
1868__weak bool arch_topdown_check_group(bool *warn)
1869{
1870 *warn = false;
1871 return false;
1872}
1873
1874__weak void arch_topdown_group_warn(void)
1875{
1876}
1877
1775/* 1878/*
1776 * Add default attributes, if there were no attributes specified or 1879 * Add default attributes, if there were no attributes specified or
1777 * if -d/--detailed, -d -d or -d -d -d is used: 1880 * if -d/--detailed, -d -d or -d -d -d is used:
1778 */ 1881 */
1779static int add_default_attributes(void) 1882static int add_default_attributes(void)
1780{ 1883{
1884 int err;
1781 struct perf_event_attr default_attrs0[] = { 1885 struct perf_event_attr default_attrs0[] = {
1782 1886
1783 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK }, 1887 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
@@ -1896,7 +2000,6 @@ static int add_default_attributes(void)
1896 return 0; 2000 return 0;
1897 2001
1898 if (transaction_run) { 2002 if (transaction_run) {
1899 int err;
1900 if (pmu_have_event("cpu", "cycles-ct") && 2003 if (pmu_have_event("cpu", "cycles-ct") &&
1901 pmu_have_event("cpu", "el-start")) 2004 pmu_have_event("cpu", "el-start"))
1902 err = parse_events(evsel_list, transaction_attrs, NULL); 2005 err = parse_events(evsel_list, transaction_attrs, NULL);
@@ -1909,6 +2012,46 @@ static int add_default_attributes(void)
1909 return 0; 2012 return 0;
1910 } 2013 }
1911 2014
2015 if (topdown_run) {
2016 char *str = NULL;
2017 bool warn = false;
2018
2019 if (stat_config.aggr_mode != AGGR_GLOBAL &&
2020 stat_config.aggr_mode != AGGR_CORE) {
2021 pr_err("top down event configuration requires --per-core mode\n");
2022 return -1;
2023 }
2024 stat_config.aggr_mode = AGGR_CORE;
2025 if (nr_cgroups || !target__has_cpu(&target)) {
2026 pr_err("top down event configuration requires system-wide mode (-a)\n");
2027 return -1;
2028 }
2029
2030 if (!force_metric_only)
2031 metric_only = true;
2032 if (topdown_filter_events(topdown_attrs, &str,
2033 arch_topdown_check_group(&warn)) < 0) {
2034 pr_err("Out of memory\n");
2035 return -1;
2036 }
2037 if (topdown_attrs[0] && str) {
2038 if (warn)
2039 arch_topdown_group_warn();
2040 err = parse_events(evsel_list, str, NULL);
2041 if (err) {
2042 fprintf(stderr,
2043 "Cannot set up top down events %s: %d\n",
2044 str, err);
2045 free(str);
2046 return -1;
2047 }
2048 } else {
2049 fprintf(stderr, "System does not support topdown\n");
2050 return -1;
2051 }
2052 free(str);
2053 }
2054
1912 if (!evsel_list->nr_entries) { 2055 if (!evsel_list->nr_entries) {
1913 if (target__has_cpu(&target)) 2056 if (target__has_cpu(&target))
1914 default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK; 2057 default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
@@ -2010,7 +2153,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2010 const char **argv = session->header.env.cmdline_argv; 2153 const char **argv = session->header.env.cmdline_argv;
2011 int argc = session->header.env.nr_cmdline; 2154 int argc = session->header.env.nr_cmdline;
2012 2155
2013 evlist__for_each(evsel_list, counter) 2156 evlist__for_each_entry(evsel_list, counter)
2014 perf_stat_process_counter(&stat_config, counter); 2157 perf_stat_process_counter(&stat_config, counter);
2015 2158
2016 if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL) 2159 if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 2a6cc254ad0c..bd108683fcb8 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -22,7 +22,7 @@
22#include "perf.h" 22#include "perf.h"
23 23
24#include "util/annotate.h" 24#include "util/annotate.h"
25#include "util/cache.h" 25#include "util/config.h"
26#include "util/color.h" 26#include "util/color.h"
27#include "util/evlist.h" 27#include "util/evlist.h"
28#include "util/evsel.h" 28#include "util/evsel.h"
@@ -295,7 +295,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
295 hists__output_recalc_col_len(hists, top->print_entries - printed); 295 hists__output_recalc_col_len(hists, top->print_entries - printed);
296 putchar('\n'); 296 putchar('\n');
297 hists__fprintf(hists, false, top->print_entries - printed, win_width, 297 hists__fprintf(hists, false, top->print_entries - printed, win_width,
298 top->min_percent, stdout); 298 top->min_percent, stdout, symbol_conf.use_callchain);
299} 299}
300 300
301static void prompt_integer(int *target, const char *msg) 301static void prompt_integer(int *target, const char *msg)
@@ -479,7 +479,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
479 479
480 fprintf(stderr, "\nAvailable events:"); 480 fprintf(stderr, "\nAvailable events:");
481 481
482 evlist__for_each(top->evlist, top->sym_evsel) 482 evlist__for_each_entry(top->evlist, top->sym_evsel)
483 fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel)); 483 fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel));
484 484
485 prompt_integer(&counter, "Enter details event counter"); 485 prompt_integer(&counter, "Enter details event counter");
@@ -490,7 +490,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
490 sleep(1); 490 sleep(1);
491 break; 491 break;
492 } 492 }
493 evlist__for_each(top->evlist, top->sym_evsel) 493 evlist__for_each_entry(top->evlist, top->sym_evsel)
494 if (top->sym_evsel->idx == counter) 494 if (top->sym_evsel->idx == counter)
495 break; 495 break;
496 } else 496 } else
@@ -583,7 +583,7 @@ static void *display_thread_tui(void *arg)
583 * Zooming in/out UIDs. For now juse use whatever the user passed 583 * Zooming in/out UIDs. For now juse use whatever the user passed
584 * via --uid. 584 * via --uid.
585 */ 585 */
586 evlist__for_each(top->evlist, pos) { 586 evlist__for_each_entry(top->evlist, pos) {
587 struct hists *hists = evsel__hists(pos); 587 struct hists *hists = evsel__hists(pos);
588 hists->uid_filter_str = top->record_opts.target.uid_str; 588 hists->uid_filter_str = top->record_opts.target.uid_str;
589 } 589 }
@@ -888,7 +888,7 @@ static int perf_top__start_counters(struct perf_top *top)
888 888
889 perf_evlist__config(evlist, opts, &callchain_param); 889 perf_evlist__config(evlist, opts, &callchain_param);
890 890
891 evlist__for_each(evlist, counter) { 891 evlist__for_each_entry(evlist, counter) {
892try_again: 892try_again:
893 if (perf_evsel__open(counter, top->evlist->cpus, 893 if (perf_evsel__open(counter, top->evlist->cpus,
894 top->evlist->threads) < 0) { 894 top->evlist->threads) < 0) {
@@ -907,7 +907,7 @@ try_again:
907 907
908 if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { 908 if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) {
909 ui__error("Failed to mmap with %d (%s)\n", 909 ui__error("Failed to mmap with %d (%s)\n",
910 errno, strerror_r(errno, msg, sizeof(msg))); 910 errno, str_error_r(errno, msg, sizeof(msg)));
911 goto out_err; 911 goto out_err;
912 } 912 }
913 913
@@ -1028,7 +1028,7 @@ out_delete:
1028 1028
1029out_err_cpu_topo: { 1029out_err_cpu_topo: {
1030 char errbuf[BUFSIZ]; 1030 char errbuf[BUFSIZ];
1031 const char *err = strerror_r(-ret, errbuf, sizeof(errbuf)); 1031 const char *err = str_error_r(-ret, errbuf, sizeof(errbuf));
1032 1032
1033 ui__error("Could not read the CPU topology map: %s\n", err); 1033 ui__error("Could not read the CPU topology map: %s\n", err);
1034 goto out_delete; 1034 goto out_delete;
@@ -1295,7 +1295,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1295 1295
1296 if (perf_evlist__create_maps(top.evlist, target) < 0) { 1296 if (perf_evlist__create_maps(top.evlist, target) < 0) {
1297 ui__error("Couldn't create thread/CPU maps: %s\n", 1297 ui__error("Couldn't create thread/CPU maps: %s\n",
1298 errno == ENOENT ? "No such process" : strerror_r(errno, errbuf, sizeof(errbuf))); 1298 errno == ENOENT ? "No such process" : str_error_r(errno, errbuf, sizeof(errbuf)));
1299 goto out_delete_evlist; 1299 goto out_delete_evlist;
1300 } 1300 }
1301 1301
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 5c50fe70d6b3..b8c6766301db 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -43,7 +43,6 @@
43#include <linux/err.h> 43#include <linux/err.h>
44#include <linux/filter.h> 44#include <linux/filter.h>
45#include <linux/audit.h> 45#include <linux/audit.h>
46#include <sys/ptrace.h>
47#include <linux/random.h> 46#include <linux/random.h>
48#include <linux/stringify.h> 47#include <linux/stringify.h>
49 48
@@ -334,6 +333,10 @@ static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
334 333
335#define SCA_FD syscall_arg__scnprintf_fd 334#define SCA_FD syscall_arg__scnprintf_fd
336 335
336#ifndef AT_FDCWD
337#define AT_FDCWD -100
338#endif
339
337static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size, 340static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size,
338 struct syscall_arg *arg) 341 struct syscall_arg *arg)
339{ 342{
@@ -1247,7 +1250,7 @@ static int trace__validate_ev_qualifier(struct trace *trace)
1247 1250
1248 i = 0; 1251 i = 0;
1249 1252
1250 strlist__for_each(pos, trace->ev_qualifier) { 1253 strlist__for_each_entry(pos, trace->ev_qualifier) {
1251 const char *sc = pos->s; 1254 const char *sc = pos->s;
1252 int id = syscalltbl__id(trace->sctbl, sc); 1255 int id = syscalltbl__id(trace->sctbl, sc);
1253 1256
@@ -1601,7 +1604,7 @@ signed_print:
1601 fprintf(trace->output, ") = %ld", ret); 1604 fprintf(trace->output, ") = %ld", ret);
1602 } else if (ret < 0 && (sc->fmt->errmsg || sc->fmt->errpid)) { 1605 } else if (ret < 0 && (sc->fmt->errmsg || sc->fmt->errpid)) {
1603 char bf[STRERR_BUFSIZE]; 1606 char bf[STRERR_BUFSIZE];
1604 const char *emsg = strerror_r(-ret, bf, sizeof(bf)), 1607 const char *emsg = str_error_r(-ret, bf, sizeof(bf)),
1605 *e = audit_errno_to_name(-ret); 1608 *e = audit_errno_to_name(-ret);
1606 1609
1607 fprintf(trace->output, ") = -1 %s %s", e, emsg); 1610 fprintf(trace->output, ") = -1 %s %s", e, emsg);
@@ -2402,7 +2405,7 @@ out_error_apply_filters:
2402 fprintf(trace->output, 2405 fprintf(trace->output,
2403 "Failed to set filter \"%s\" on event %s with %d (%s)\n", 2406 "Failed to set filter \"%s\" on event %s with %d (%s)\n",
2404 evsel->filter, perf_evsel__name(evsel), errno, 2407 evsel->filter, perf_evsel__name(evsel), errno,
2405 strerror_r(errno, errbuf, sizeof(errbuf))); 2408 str_error_r(errno, errbuf, sizeof(errbuf)));
2406 goto out_delete_evlist; 2409 goto out_delete_evlist;
2407} 2410}
2408out_error_mem: 2411out_error_mem:
@@ -2483,7 +2486,7 @@ static int trace__replay(struct trace *trace)
2483 goto out; 2486 goto out;
2484 } 2487 }
2485 2488
2486 evlist__for_each(session->evlist, evsel) { 2489 evlist__for_each_entry(session->evlist, evsel) {
2487 if (evsel->attr.type == PERF_TYPE_SOFTWARE && 2490 if (evsel->attr.type == PERF_TYPE_SOFTWARE &&
2488 (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ || 2491 (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ||
2489 evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MIN || 2492 evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MIN ||
@@ -2550,7 +2553,7 @@ static size_t thread__dump_stats(struct thread_trace *ttrace,
2550 printed += fprintf(fp, " (msec) (msec) (msec) (msec) (%%)\n"); 2553 printed += fprintf(fp, " (msec) (msec) (msec) (msec) (%%)\n");
2551 printed += fprintf(fp, " --------------- -------- --------- --------- --------- --------- ------\n"); 2554 printed += fprintf(fp, " --------------- -------- --------- --------- --------- --------- ------\n");
2552 2555
2553 resort_rb__for_each(nd, syscall_stats) { 2556 resort_rb__for_each_entry(nd, syscall_stats) {
2554 struct stats *stats = syscall_stats_entry->stats; 2557 struct stats *stats = syscall_stats_entry->stats;
2555 if (stats) { 2558 if (stats) {
2556 double min = (double)(stats->min) / NSEC_PER_MSEC; 2559 double min = (double)(stats->min) / NSEC_PER_MSEC;
@@ -2627,7 +2630,7 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
2627 return 0; 2630 return 0;
2628 } 2631 }
2629 2632
2630 resort_rb__for_each(nd, threads) 2633 resort_rb__for_each_entry(nd, threads)
2631 printed += trace__fprintf_thread(fp, threads_entry->thread, trace); 2634 printed += trace__fprintf_thread(fp, threads_entry->thread, trace);
2632 2635
2633 resort_rb__delete(threads); 2636 resort_rb__delete(threads);
@@ -2714,7 +2717,7 @@ static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
2714{ 2717{
2715 struct perf_evsel *evsel; 2718 struct perf_evsel *evsel;
2716 2719
2717 evlist__for_each(evlist, evsel) 2720 evlist__for_each_entry(evlist, evsel)
2718 evsel->handler = handler; 2721 evsel->handler = handler;
2719} 2722}
2720 2723
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 5ad0255f8756..24803c58049a 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -73,17 +73,25 @@ endif
73# 73#
74# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/ 74# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
75# 75#
76
77libunwind_arch_set_flags = $(eval $(libunwind_arch_set_flags_code))
78define libunwind_arch_set_flags_code
79 FEATURE_CHECK_CFLAGS-libunwind-$(1) = -I$(LIBUNWIND_DIR)/include
80 FEATURE_CHECK_LDFLAGS-libunwind-$(1) = -L$(LIBUNWIND_DIR)/lib
81endef
82
76ifdef LIBUNWIND_DIR 83ifdef LIBUNWIND_DIR
77 LIBUNWIND_CFLAGS = -I$(LIBUNWIND_DIR)/include 84 LIBUNWIND_CFLAGS = -I$(LIBUNWIND_DIR)/include
78 LIBUNWIND_LDFLAGS = -L$(LIBUNWIND_DIR)/lib 85 LIBUNWIND_LDFLAGS = -L$(LIBUNWIND_DIR)/lib
86 LIBUNWIND_ARCHS = x86 x86_64 arm aarch64 debug-frame-arm debug-frame-aarch64
87 $(foreach libunwind_arch,$(LIBUNWIND_ARCHS),$(call libunwind_arch_set_flags,$(libunwind_arch)))
79endif 88endif
80LIBUNWIND_LDFLAGS += $(LIBUNWIND_LIBS)
81 89
82# Set per-feature check compilation flags 90# Set per-feature check compilation flags
83FEATURE_CHECK_CFLAGS-libunwind = $(LIBUNWIND_CFLAGS) 91FEATURE_CHECK_CFLAGS-libunwind = $(LIBUNWIND_CFLAGS)
84FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS) 92FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS)
85FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS) 93FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS)
86FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS) 94FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS) $(LIBUNWIND_LIBS)
87 95
88ifeq ($(NO_PERF_REGS),0) 96ifeq ($(NO_PERF_REGS),0)
89 CFLAGS += -DHAVE_PERF_REGS_SUPPORT 97 CFLAGS += -DHAVE_PERF_REGS_SUPPORT
@@ -107,7 +115,7 @@ endif
107FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS) 115FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS)
108FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf 116FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
109 117
110FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/arch/$(ARCH)/include/uapi -I$(srctree)/include/uapi 118FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi
111# include ARCH specific config 119# include ARCH specific config
112-include $(src-perf)/arch/$(ARCH)/Makefile 120-include $(src-perf)/arch/$(ARCH)/Makefile
113 121
@@ -198,11 +206,11 @@ endif
198 206
199CFLAGS += -I$(src-perf)/util/include 207CFLAGS += -I$(src-perf)/util/include
200CFLAGS += -I$(src-perf)/arch/$(ARCH)/include 208CFLAGS += -I$(src-perf)/arch/$(ARCH)/include
209CFLAGS += -I$(srctree)/tools/include/uapi
201CFLAGS += -I$(srctree)/tools/include/ 210CFLAGS += -I$(srctree)/tools/include/
202CFLAGS += -I$(srctree)/arch/$(ARCH)/include/uapi 211CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi
203CFLAGS += -I$(srctree)/arch/$(ARCH)/include 212CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/
204CFLAGS += -I$(srctree)/include/uapi 213CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/
205CFLAGS += -I$(srctree)/include
206 214
207# $(obj-perf) for generated common-cmds.h 215# $(obj-perf) for generated common-cmds.h
208# $(obj-perf)/util for generated bison/flex headers 216# $(obj-perf)/util for generated bison/flex headers
@@ -249,7 +257,7 @@ else
249 LIBC_SUPPORT := 1 257 LIBC_SUPPORT := 1
250 endif 258 endif
251 ifeq ($(LIBC_SUPPORT),1) 259 ifeq ($(LIBC_SUPPORT),1)
252 msg := $(warning No libelf found, disables 'probe' tool and BPF support in 'perf record', please install elfutils-libelf-devel/libelf-dev); 260 msg := $(warning No libelf found, disables 'probe' tool and BPF support in 'perf record', please install libelf-dev, libelf-devel or elfutils-libelf-devel);
253 261
254 NO_LIBELF := 1 262 NO_LIBELF := 1
255 NO_DWARF := 1 263 NO_DWARF := 1
@@ -301,6 +309,16 @@ ifndef NO_LIBELF
301 CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT 309 CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT
302 endif 310 endif
303 311
312 ifeq ($(feature-libelf-gelf_getnote), 1)
313 CFLAGS += -DHAVE_GELF_GETNOTE_SUPPORT
314 else
315 msg := $(warning gelf_getnote() not found on libelf, SDT support disabled);
316 endif
317
318 ifeq ($(feature-libelf-getshdrstrndx), 1)
319 CFLAGS += -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT
320 endif
321
304 ifndef NO_DWARF 322 ifndef NO_DWARF
305 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) 323 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
306 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); 324 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
@@ -337,6 +355,16 @@ ifndef NO_LIBELF
337 endif # NO_LIBBPF 355 endif # NO_LIBBPF
338endif # NO_LIBELF 356endif # NO_LIBELF
339 357
358ifndef NO_SDT
359 ifneq ($(feature-sdt), 1)
360 msg := $(warning No sys/sdt.h found, no SDT events are defined, please install systemtap-sdt-devel or systemtap-sdt-dev);
361 NO_SDT := 1;
362 else
363 CFLAGS += -DHAVE_SDT_EVENT
364 $(call detected,CONFIG_SDT_EVENT)
365 endif
366endif
367
340ifdef PERF_HAVE_JITDUMP 368ifdef PERF_HAVE_JITDUMP
341 ifndef NO_DWARF 369 ifndef NO_DWARF
342 $(call detected,CONFIG_JITDUMP) 370 $(call detected,CONFIG_JITDUMP)
@@ -351,10 +379,42 @@ ifeq ($(ARCH),powerpc)
351endif 379endif
352 380
353ifndef NO_LIBUNWIND 381ifndef NO_LIBUNWIND
382 have_libunwind :=
383
384 ifeq ($(feature-libunwind-x86), 1)
385 $(call detected,CONFIG_LIBUNWIND_X86)
386 CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT
387 LDFLAGS += -lunwind-x86
388 EXTLIBS_LIBUNWIND += -lunwind-x86
389 have_libunwind = 1
390 endif
391
392 ifeq ($(feature-libunwind-aarch64), 1)
393 $(call detected,CONFIG_LIBUNWIND_AARCH64)
394 CFLAGS += -DHAVE_LIBUNWIND_AARCH64_SUPPORT
395 LDFLAGS += -lunwind-aarch64
396 EXTLIBS_LIBUNWIND += -lunwind-aarch64
397 have_libunwind = 1
398 $(call feature_check,libunwind-debug-frame-aarch64)
399 ifneq ($(feature-libunwind-debug-frame-aarch64), 1)
400 msg := $(warning No debug_frame support found in libunwind-aarch64);
401 CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME_AARCH64
402 endif
403 endif
404
354 ifneq ($(feature-libunwind), 1) 405 ifneq ($(feature-libunwind), 1)
355 msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR); 406 msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
407 NO_LOCAL_LIBUNWIND := 1
408 else
409 have_libunwind := 1
410 $(call detected,CONFIG_LOCAL_LIBUNWIND)
411 endif
412
413 ifneq ($(have_libunwind), 1)
356 NO_LIBUNWIND := 1 414 NO_LIBUNWIND := 1
357 endif 415 endif
416else
417 NO_LOCAL_LIBUNWIND := 1
358endif 418endif
359 419
360ifndef NO_LIBBPF 420ifndef NO_LIBBPF
@@ -392,7 +452,7 @@ else
392 NO_DWARF_UNWIND := 1 452 NO_DWARF_UNWIND := 1
393endif 453endif
394 454
395ifndef NO_LIBUNWIND 455ifndef NO_LOCAL_LIBUNWIND
396 ifeq ($(ARCH),$(filter $(ARCH),arm arm64)) 456 ifeq ($(ARCH),$(filter $(ARCH),arm arm64))
397 $(call feature_check,libunwind-debug-frame) 457 $(call feature_check,libunwind-debug-frame)
398 ifneq ($(feature-libunwind-debug-frame), 1) 458 ifneq ($(feature-libunwind-debug-frame), 1)
@@ -403,10 +463,15 @@ ifndef NO_LIBUNWIND
403 # non-ARM has no dwarf_find_debug_frame() function: 463 # non-ARM has no dwarf_find_debug_frame() function:
404 CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME 464 CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
405 endif 465 endif
406 CFLAGS += -DHAVE_LIBUNWIND_SUPPORT
407 EXTLIBS += $(LIBUNWIND_LIBS) 466 EXTLIBS += $(LIBUNWIND_LIBS)
467 LDFLAGS += $(LIBUNWIND_LIBS)
468endif
469
470ifndef NO_LIBUNWIND
471 CFLAGS += -DHAVE_LIBUNWIND_SUPPORT
408 CFLAGS += $(LIBUNWIND_CFLAGS) 472 CFLAGS += $(LIBUNWIND_CFLAGS)
409 LDFLAGS += $(LIBUNWIND_LDFLAGS) 473 LDFLAGS += $(LIBUNWIND_LDFLAGS)
474 EXTLIBS += $(EXTLIBS_LIBUNWIND)
410endif 475endif
411 476
412ifndef NO_LIBAUDIT 477ifndef NO_LIBAUDIT
@@ -437,7 +502,7 @@ endif
437 502
438ifndef NO_SLANG 503ifndef NO_SLANG
439 ifneq ($(feature-libslang), 1) 504 ifneq ($(feature-libslang), 1)
440 msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev); 505 msg := $(warning slang not found, disables TUI support. Please install slang-devel, libslang-dev or libslang2-dev);
441 NO_SLANG := 1 506 NO_SLANG := 1
442 else 507 else
443 # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h 508 # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
diff --git a/tools/perf/jvmti/jvmti_agent.c b/tools/perf/jvmti/jvmti_agent.c
index 3573f315f955..55daefff0d54 100644
--- a/tools/perf/jvmti/jvmti_agent.c
+++ b/tools/perf/jvmti/jvmti_agent.c
@@ -59,7 +59,6 @@ static int get_e_machine(struct jitheader *hdr)
59 ssize_t sret; 59 ssize_t sret;
60 char id[16]; 60 char id[16];
61 int fd, ret = -1; 61 int fd, ret = -1;
62 int m = -1;
63 struct { 62 struct {
64 uint16_t e_type; 63 uint16_t e_type;
65 uint16_t e_machine; 64 uint16_t e_machine;
@@ -81,11 +80,7 @@ static int get_e_machine(struct jitheader *hdr)
81 if (sret != sizeof(info)) 80 if (sret != sizeof(info))
82 goto error; 81 goto error;
83 82
84 m = info.e_machine; 83 hdr->elf_mach = info.e_machine;
85 if (m < 0)
86 m = 0; /* ELF EM_NONE */
87
88 hdr->elf_mach = m;
89 ret = 0; 84 ret = 0;
90error: 85error:
91 close(fd); 86 close(fd);
@@ -491,10 +486,11 @@ jvmti_write_debug_info(void *agent, uint64_t code, const char *file,
491 if (sret != 1) 486 if (sret != 1)
492 goto error; 487 goto error;
493 } 488 }
494 if (padding_count) 489 if (padding_count) {
495 sret = fwrite_unlocked(pad_bytes, padding_count, 1, fp); 490 sret = fwrite_unlocked(pad_bytes, padding_count, 1, fp);
496 if (sret != 1) 491 if (sret != 1)
497 goto error; 492 goto error;
493 }
498 494
499 funlockfile(fp); 495 funlockfile(fp);
500 return 0; 496 return 0;
diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h
index 83a25cef82fd..7ed72a475c57 100644
--- a/tools/perf/perf-sys.h
+++ b/tools/perf/perf-sys.h
@@ -5,35 +5,18 @@
5#include <sys/types.h> 5#include <sys/types.h>
6#include <sys/syscall.h> 6#include <sys/syscall.h>
7#include <linux/types.h> 7#include <linux/types.h>
8#include <linux/compiler.h>
8#include <linux/perf_event.h> 9#include <linux/perf_event.h>
9#include <asm/barrier.h> 10#include <asm/barrier.h>
10 11
11#if defined(__i386__) 12#if defined(__i386__)
12#define cpu_relax() asm volatile("rep; nop" ::: "memory"); 13#define cpu_relax() asm volatile("rep; nop" ::: "memory");
13#define CPUINFO_PROC {"model name"} 14#define CPUINFO_PROC {"model name"}
14#ifndef __NR_perf_event_open
15# define __NR_perf_event_open 336
16#endif
17#ifndef __NR_futex
18# define __NR_futex 240
19#endif
20#ifndef __NR_gettid
21# define __NR_gettid 224
22#endif
23#endif 15#endif
24 16
25#if defined(__x86_64__) 17#if defined(__x86_64__)
26#define cpu_relax() asm volatile("rep; nop" ::: "memory"); 18#define cpu_relax() asm volatile("rep; nop" ::: "memory");
27#define CPUINFO_PROC {"model name"} 19#define CPUINFO_PROC {"model name"}
28#ifndef __NR_perf_event_open
29# define __NR_perf_event_open 298
30#endif
31#ifndef __NR_futex
32# define __NR_futex 202
33#endif
34#ifndef __NR_gettid
35# define __NR_gettid 186
36#endif
37#endif 20#endif
38 21
39#ifdef __powerpc__ 22#ifdef __powerpc__
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 15982cee5ef3..64c06961bfe4 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -10,7 +10,7 @@
10 10
11#include "util/env.h" 11#include "util/env.h"
12#include <subcmd/exec-cmd.h> 12#include <subcmd/exec-cmd.h>
13#include "util/cache.h" 13#include "util/config.h"
14#include "util/quote.h" 14#include "util/quote.h"
15#include <subcmd/run-command.h> 15#include <subcmd/run-command.h>
16#include "util/parse-events.h" 16#include "util/parse-events.h"
@@ -139,8 +139,6 @@ struct option options[] = {
139 OPT_ARGUMENT("html-path", "html-path"), 139 OPT_ARGUMENT("html-path", "html-path"),
140 OPT_ARGUMENT("paginate", "paginate"), 140 OPT_ARGUMENT("paginate", "paginate"),
141 OPT_ARGUMENT("no-pager", "no-pager"), 141 OPT_ARGUMENT("no-pager", "no-pager"),
142 OPT_ARGUMENT("perf-dir", "perf-dir"),
143 OPT_ARGUMENT("work-tree", "work-tree"),
144 OPT_ARGUMENT("debugfs-dir", "debugfs-dir"), 142 OPT_ARGUMENT("debugfs-dir", "debugfs-dir"),
145 OPT_ARGUMENT("buildid-dir", "buildid-dir"), 143 OPT_ARGUMENT("buildid-dir", "buildid-dir"),
146 OPT_ARGUMENT("list-cmds", "list-cmds"), 144 OPT_ARGUMENT("list-cmds", "list-cmds"),
@@ -200,35 +198,6 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
200 use_pager = 0; 198 use_pager = 0;
201 if (envchanged) 199 if (envchanged)
202 *envchanged = 1; 200 *envchanged = 1;
203 } else if (!strcmp(cmd, "--perf-dir")) {
204 if (*argc < 2) {
205 fprintf(stderr, "No directory given for --perf-dir.\n");
206 usage(perf_usage_string);
207 }
208 setenv(PERF_DIR_ENVIRONMENT, (*argv)[1], 1);
209 if (envchanged)
210 *envchanged = 1;
211 (*argv)++;
212 (*argc)--;
213 handled++;
214 } else if (!prefixcmp(cmd, CMD_PERF_DIR)) {
215 setenv(PERF_DIR_ENVIRONMENT, cmd + strlen(CMD_PERF_DIR), 1);
216 if (envchanged)
217 *envchanged = 1;
218 } else if (!strcmp(cmd, "--work-tree")) {
219 if (*argc < 2) {
220 fprintf(stderr, "No directory given for --work-tree.\n");
221 usage(perf_usage_string);
222 }
223 setenv(PERF_WORK_TREE_ENVIRONMENT, (*argv)[1], 1);
224 if (envchanged)
225 *envchanged = 1;
226 (*argv)++;
227 (*argc)--;
228 } else if (!prefixcmp(cmd, CMD_WORK_TREE)) {
229 setenv(PERF_WORK_TREE_ENVIRONMENT, cmd + strlen(CMD_WORK_TREE), 1);
230 if (envchanged)
231 *envchanged = 1;
232 } else if (!strcmp(cmd, "--debugfs-dir")) { 201 } else if (!strcmp(cmd, "--debugfs-dir")) {
233 if (*argc < 2) { 202 if (*argc < 2) {
234 fprintf(stderr, "No directory given for --debugfs-dir.\n"); 203 fprintf(stderr, "No directory given for --debugfs-dir.\n");
@@ -363,11 +332,6 @@ const char perf_version_string[] = PERF_VERSION;
363 332
364#define RUN_SETUP (1<<0) 333#define RUN_SETUP (1<<0)
365#define USE_PAGER (1<<1) 334#define USE_PAGER (1<<1)
366/*
367 * require working tree to be present -- anything uses this needs
368 * RUN_SETUP for reading from the configuration file.
369 */
370#define NEED_WORK_TREE (1<<2)
371 335
372static int run_builtin(struct cmd_struct *p, int argc, const char **argv) 336static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
373{ 337{
@@ -391,6 +355,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
391 355
392 perf_env__set_cmdline(&perf_env, argc, argv); 356 perf_env__set_cmdline(&perf_env, argc, argv);
393 status = p->fn(argc, argv, prefix); 357 status = p->fn(argc, argv, prefix);
358 perf_config__exit();
394 exit_browser(status); 359 exit_browser(status);
395 perf_env__exit(&perf_env); 360 perf_env__exit(&perf_env);
396 bpf__clear(); 361 bpf__clear();
@@ -409,7 +374,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
409 /* Check for ENOSPC and EIO errors.. */ 374 /* Check for ENOSPC and EIO errors.. */
410 if (fflush(stdout)) { 375 if (fflush(stdout)) {
411 fprintf(stderr, "write failure on standard output: %s", 376 fprintf(stderr, "write failure on standard output: %s",
412 strerror_r(errno, sbuf, sizeof(sbuf))); 377 str_error_r(errno, sbuf, sizeof(sbuf)));
413 goto out; 378 goto out;
414 } 379 }
415 if (ferror(stdout)) { 380 if (ferror(stdout)) {
@@ -418,7 +383,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
418 } 383 }
419 if (fclose(stdout)) { 384 if (fclose(stdout)) {
420 fprintf(stderr, "close failed on standard output: %s", 385 fprintf(stderr, "close failed on standard output: %s",
421 strerror_r(errno, sbuf, sizeof(sbuf))); 386 str_error_r(errno, sbuf, sizeof(sbuf)));
422 goto out; 387 goto out;
423 } 388 }
424 status = 0; 389 status = 0;
@@ -532,6 +497,16 @@ void pthread__unblock_sigwinch(void)
532 pthread_sigmask(SIG_UNBLOCK, &set, NULL); 497 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
533} 498}
534 499
500#ifdef _SC_LEVEL1_DCACHE_LINESIZE
501#define cache_line_size(cacheline_sizep) *cacheline_sizep = sysconf(_SC_LEVEL1_DCACHE_LINESIZE)
502#else
503static void cache_line_size(int *cacheline_sizep)
504{
505 if (sysfs__read_int("devices/system/cpu/cpu0/cache/index0/coherency_line_size", cacheline_sizep))
506 pr_debug("cannot determine cache line size");
507}
508#endif
509
535int main(int argc, const char **argv) 510int main(int argc, const char **argv)
536{ 511{
537 const char *cmd; 512 const char *cmd;
@@ -544,7 +519,7 @@ int main(int argc, const char **argv)
544 519
545 /* The page_size is placed in util object. */ 520 /* The page_size is placed in util object. */
546 page_size = sysconf(_SC_PAGE_SIZE); 521 page_size = sysconf(_SC_PAGE_SIZE);
547 cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); 522 cache_line_size(&cacheline_size);
548 523
549 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0) 524 if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0)
550 sysctl_perf_event_max_stack = value; 525 sysctl_perf_event_max_stack = value;
@@ -558,6 +533,7 @@ int main(int argc, const char **argv)
558 533
559 srandom(time(NULL)); 534 srandom(time(NULL));
560 535
536 perf_config__init();
561 perf_config(perf_default_config, NULL); 537 perf_config(perf_default_config, NULL);
562 set_buildid_dir(NULL); 538 set_buildid_dir(NULL);
563 539
@@ -649,7 +625,7 @@ int main(int argc, const char **argv)
649 } 625 }
650 626
651 fprintf(stderr, "Failed to run command '%s': %s\n", 627 fprintf(stderr, "Failed to run command '%s': %s\n",
652 cmd, strerror_r(errno, sbuf, sizeof(sbuf))); 628 cmd, str_error_r(errno, sbuf, sizeof(sbuf)));
653out: 629out:
654 return 1; 630 return 1;
655} 631}
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index cd8f1b150f9e..a7e0f1497244 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -59,6 +59,8 @@ struct record_opts {
59 bool record_switch_events; 59 bool record_switch_events;
60 bool all_kernel; 60 bool all_kernel;
61 bool all_user; 61 bool all_user;
62 bool tail_synthesize;
63 bool overwrite;
62 unsigned int freq; 64 unsigned int freq;
63 unsigned int mmap_pages; 65 unsigned int mmap_pages;
64 unsigned int auxtrace_mmap_pages; 66 unsigned int auxtrace_mmap_pages;
diff --git a/tools/perf/python/tracepoint.py b/tools/perf/python/tracepoint.py
new file mode 100755
index 000000000000..eb4dbed57de7
--- /dev/null
+++ b/tools/perf/python/tracepoint.py
@@ -0,0 +1,47 @@
1#! /usr/bin/python
2# -*- python -*-
3# -*- coding: utf-8 -*-
4
5import perf
6
7class tracepoint(perf.evsel):
8 def __init__(self, sys, name):
9 config = perf.tracepoint(sys, name)
10 perf.evsel.__init__(self,
11 type = perf.TYPE_TRACEPOINT,
12 config = config,
13 freq = 0, sample_period = 1, wakeup_events = 1,
14 sample_type = perf.SAMPLE_PERIOD | perf.SAMPLE_TID | perf.SAMPLE_CPU | perf.SAMPLE_RAW | perf.SAMPLE_TIME)
15
16def main():
17 tp = tracepoint("sched", "sched_switch")
18 cpus = perf.cpu_map()
19 threads = perf.thread_map(-1)
20
21 evlist = perf.evlist(cpus, threads)
22 evlist.add(tp)
23 evlist.open()
24 evlist.mmap()
25
26 while True:
27 evlist.poll(timeout = -1)
28 for cpu in cpus:
29 event = evlist.read_on_cpu(cpu)
30 if not event:
31 continue
32
33 if not isinstance(event, perf.sample_event):
34 continue
35
36 print "time %u prev_comm=%s prev_pid=%d prev_prio=%d prev_state=0x%x ==> next_comm=%s next_pid=%d next_prio=%d" % (
37 event.sample_time,
38 event.prev_comm,
39 event.prev_pid,
40 event.prev_prio,
41 event.prev_state,
42 event.next_comm,
43 event.next_pid,
44 event.next_prio)
45
46if __name__ == '__main__':
47 main()
diff --git a/tools/perf/scripts/python/bin/stackcollapse-record b/tools/perf/scripts/python/bin/stackcollapse-record
new file mode 100755
index 000000000000..9d8f9f0f3a17
--- /dev/null
+++ b/tools/perf/scripts/python/bin/stackcollapse-record
@@ -0,0 +1,8 @@
1#!/bin/sh
2
3#
4# stackcollapse.py can cover all type of perf samples including
5# the tracepoints, so no special record requirements, just record what
6# you want to analyze.
7#
8perf record "$@"
diff --git a/tools/perf/scripts/python/bin/stackcollapse-report b/tools/perf/scripts/python/bin/stackcollapse-report
new file mode 100755
index 000000000000..356b9656393d
--- /dev/null
+++ b/tools/perf/scripts/python/bin/stackcollapse-report
@@ -0,0 +1,3 @@
1#!/bin/sh
2# description: produce callgraphs in short form for scripting use
3perf script -s "$PERF_EXEC_PATH"/scripts/python/stackcollapse.py -- "$@"
diff --git a/tools/perf/scripts/python/netdev-times.py b/tools/perf/scripts/python/netdev-times.py
index 4d21ef2d601d..4c6f09ac7d12 100644
--- a/tools/perf/scripts/python/netdev-times.py
+++ b/tools/perf/scripts/python/netdev-times.py
@@ -252,9 +252,10 @@ def irq__irq_handler_exit(name, context, cpu, sec, nsec, pid, comm, callchain, i
252 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret) 252 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret)
253 all_event_list.append(event_info) 253 all_event_list.append(event_info)
254 254
255def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi, dev_name): 255def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi,
256 dev_name, work=None, budget=None):
256 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, 257 event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
257 napi, dev_name) 258 napi, dev_name, work, budget)
258 all_event_list.append(event_info) 259 all_event_list.append(event_info)
259 260
260def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr, 261def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr,
@@ -354,11 +355,13 @@ def handle_irq_softirq_exit(event_info):
354 receive_hunk_list.append(rec_data) 355 receive_hunk_list.append(rec_data)
355 356
356def handle_napi_poll(event_info): 357def handle_napi_poll(event_info):
357 (name, context, cpu, time, pid, comm, napi, dev_name) = event_info 358 (name, context, cpu, time, pid, comm, napi, dev_name,
359 work, budget) = event_info
358 if cpu in net_rx_dic.keys(): 360 if cpu in net_rx_dic.keys():
359 event_list = net_rx_dic[cpu]['event_list'] 361 event_list = net_rx_dic[cpu]['event_list']
360 rec_data = {'event_name':'napi_poll', 362 rec_data = {'event_name':'napi_poll',
361 'dev':dev_name, 'event_t':time} 363 'dev':dev_name, 'event_t':time,
364 'work':work, 'budget':budget}
362 event_list.append(rec_data) 365 event_list.append(rec_data)
363 366
364def handle_netif_rx(event_info): 367def handle_netif_rx(event_info):
diff --git a/tools/perf/scripts/python/stackcollapse.py b/tools/perf/scripts/python/stackcollapse.py
new file mode 100755
index 000000000000..5a605f70ef32
--- /dev/null
+++ b/tools/perf/scripts/python/stackcollapse.py
@@ -0,0 +1,125 @@
1# stackcollapse.py - format perf samples with one line per distinct call stack
2#
3# This script's output has two space-separated fields. The first is a semicolon
4# separated stack including the program name (from the "comm" field) and the
5# function names from the call stack. The second is a count:
6#
7# swapper;start_kernel;rest_init;cpu_idle;default_idle;native_safe_halt 2
8#
9# The file is sorted according to the first field.
10#
11# Input may be created and processed using:
12#
13# perf record -a -g -F 99 sleep 60
14# perf script report stackcollapse > out.stacks-folded
15#
16# (perf script record stackcollapse works too).
17#
18# Written by Paolo Bonzini <pbonzini@redhat.com>
19# Based on Brendan Gregg's stackcollapse-perf.pl script.
20
21import os
22import sys
23from collections import defaultdict
24from optparse import OptionParser, make_option
25
26sys.path.append(os.environ['PERF_EXEC_PATH'] + \
27 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
28
29from perf_trace_context import *
30from Core import *
31from EventClass import *
32
33# command line parsing
34
35option_list = [
36 # formatting options for the bottom entry of the stack
37 make_option("--include-tid", dest="include_tid",
38 action="store_true", default=False,
39 help="include thread id in stack"),
40 make_option("--include-pid", dest="include_pid",
41 action="store_true", default=False,
42 help="include process id in stack"),
43 make_option("--no-comm", dest="include_comm",
44 action="store_false", default=True,
45 help="do not separate stacks according to comm"),
46 make_option("--tidy-java", dest="tidy_java",
47 action="store_true", default=False,
48 help="beautify Java signatures"),
49 make_option("--kernel", dest="annotate_kernel",
50 action="store_true", default=False,
51 help="annotate kernel functions with _[k]")
52]
53
54parser = OptionParser(option_list=option_list)
55(opts, args) = parser.parse_args()
56
57if len(args) != 0:
58 parser.error("unexpected command line argument")
59if opts.include_tid and not opts.include_comm:
60 parser.error("requesting tid but not comm is invalid")
61if opts.include_pid and not opts.include_comm:
62 parser.error("requesting pid but not comm is invalid")
63
64# event handlers
65
66lines = defaultdict(lambda: 0)
67
68def process_event(param_dict):
69 def tidy_function_name(sym, dso):
70 if sym is None:
71 sym = '[unknown]'
72
73 sym = sym.replace(';', ':')
74 if opts.tidy_java:
75 # the original stackcollapse-perf.pl script gives the
76 # example of converting this:
77 # Lorg/mozilla/javascript/MemberBox;.<init>(Ljava/lang/reflect/Method;)V
78 # to this:
79 # org/mozilla/javascript/MemberBox:.init
80 sym = sym.replace('<', '')
81 sym = sym.replace('>', '')
82 if sym[0] == 'L' and sym.find('/'):
83 sym = sym[1:]
84 try:
85 sym = sym[:sym.index('(')]
86 except ValueError:
87 pass
88
89 if opts.annotate_kernel and dso == '[kernel.kallsyms]':
90 return sym + '_[k]'
91 else:
92 return sym
93
94 stack = list()
95 if 'callchain' in param_dict:
96 for entry in param_dict['callchain']:
97 entry.setdefault('sym', dict())
98 entry['sym'].setdefault('name', None)
99 entry.setdefault('dso', None)
100 stack.append(tidy_function_name(entry['sym']['name'],
101 entry['dso']))
102 else:
103 param_dict.setdefault('symbol', None)
104 param_dict.setdefault('dso', None)
105 stack.append(tidy_function_name(param_dict['symbol'],
106 param_dict['dso']))
107
108 if opts.include_comm:
109 comm = param_dict["comm"].replace(' ', '_')
110 sep = "-"
111 if opts.include_pid:
112 comm = comm + sep + str(param_dict['sample']['pid'])
113 sep = "/"
114 if opts.include_tid:
115 comm = comm + sep + str(param_dict['sample']['tid'])
116 stack.append(comm)
117
118 stack_string = ';'.join(reversed(stack))
119 lines[stack_string] = lines[stack_string] + 1
120
121def trace_end():
122 list = lines.keys()
123 list.sort()
124 for stack in list:
125 print "%s %d" % (stack, lines[stack])
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 66a28982547b..cb20ae1c0d35 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -39,6 +39,8 @@ perf-y += stat.o
39perf-y += event_update.o 39perf-y += event_update.o
40perf-y += event-times.o 40perf-y += event-times.o
41perf-y += backward-ring-buffer.o 41perf-y += backward-ring-buffer.o
42perf-y += sdt.o
43perf-y += is_printable_array.o
42 44
43$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build 45$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
44 $(call rule_mkdir) 46 $(call rule_mkdir)
diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c
index d9ba991a9a30..615780cbfe1d 100644
--- a/tools/perf/tests/backward-ring-buffer.c
+++ b/tools/perf/tests/backward-ring-buffer.c
@@ -31,8 +31,8 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count,
31 for (i = 0; i < evlist->nr_mmaps; i++) { 31 for (i = 0; i < evlist->nr_mmaps; i++) {
32 union perf_event *event; 32 union perf_event *event;
33 33
34 perf_evlist__mmap_read_catchup(evlist, i); 34 perf_mmap__read_catchup(&evlist->backward_mmap[i]);
35 while ((event = perf_evlist__mmap_read_backward(evlist, i)) != NULL) { 35 while ((event = perf_mmap__read_backward(&evlist->backward_mmap[i])) != NULL) {
36 const u32 type = event->header.type; 36 const u32 type = event->header.type;
37 37
38 switch (type) { 38 switch (type) {
@@ -60,7 +60,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages,
60 err = perf_evlist__mmap(evlist, mmap_pages, true); 60 err = perf_evlist__mmap(evlist, mmap_pages, true);
61 if (err < 0) { 61 if (err < 0) {
62 pr_debug("perf_evlist__mmap: %s\n", 62 pr_debug("perf_evlist__mmap: %s\n",
63 strerror_r(errno, sbuf, sizeof(sbuf))); 63 str_error_r(errno, sbuf, sizeof(sbuf)));
64 return TEST_FAIL; 64 return TEST_FAIL;
65 } 65 }
66 66
@@ -108,7 +108,11 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
108 } 108 }
109 109
110 bzero(&parse_error, sizeof(parse_error)); 110 bzero(&parse_error, sizeof(parse_error));
111 err = parse_events(evlist, "syscalls:sys_enter_prctl", &parse_error); 111 /*
112 * Set backward bit, ring buffer should be writing from end. Record
113 * it in aux evlist
114 */
115 err = parse_events(evlist, "syscalls:sys_enter_prctl/overwrite/", &parse_error);
112 if (err) { 116 if (err) {
113 pr_debug("Failed to parse tracepoint event, try use root\n"); 117 pr_debug("Failed to parse tracepoint event, try use root\n");
114 ret = TEST_SKIP; 118 ret = TEST_SKIP;
@@ -117,14 +121,10 @@ int test__backward_ring_buffer(int subtest __maybe_unused)
117 121
118 perf_evlist__config(evlist, &opts, NULL); 122 perf_evlist__config(evlist, &opts, NULL);
119 123
120 /* Set backward bit, ring buffer should be writing from end */
121 evlist__for_each(evlist, evsel)
122 evsel->attr.write_backward = 1;
123
124 err = perf_evlist__open(evlist); 124 err = perf_evlist__open(evlist);
125 if (err < 0) { 125 if (err < 0) {
126 pr_debug("perf_evlist__open: %s\n", 126 pr_debug("perf_evlist__open: %s\n",
127 strerror_r(errno, sbuf, sizeof(sbuf))); 127 str_error_r(errno, sbuf, sizeof(sbuf)));
128 goto out_delete_evlist; 128 goto out_delete_evlist;
129 } 129 }
130 130
diff --git a/tools/perf/tests/bpf-script-example.c b/tools/perf/tests/bpf-script-example.c
index 0ec9c2c03164..e53bc91fa260 100644
--- a/tools/perf/tests/bpf-script-example.c
+++ b/tools/perf/tests/bpf-script-example.c
@@ -31,8 +31,8 @@ struct bpf_map_def SEC("maps") flip_table = {
31 .max_entries = 1, 31 .max_entries = 1,
32}; 32};
33 33
34SEC("func=sys_epoll_pwait") 34SEC("func=sys_epoll_wait")
35int bpf_func__sys_epoll_pwait(void *ctx) 35int bpf_func__sys_epoll_wait(void *ctx)
36{ 36{
37 int ind =0; 37 int ind =0;
38 int *flag = bpf_map_lookup_elem(&flip_table, &ind); 38 int *flag = bpf_map_lookup_elem(&flip_table, &ind);
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
index f31eed31c1a9..fc54064b9186 100644
--- a/tools/perf/tests/bpf.c
+++ b/tools/perf/tests/bpf.c
@@ -13,13 +13,13 @@
13 13
14#ifdef HAVE_LIBBPF_SUPPORT 14#ifdef HAVE_LIBBPF_SUPPORT
15 15
16static int epoll_pwait_loop(void) 16static int epoll_wait_loop(void)
17{ 17{
18 int i; 18 int i;
19 19
20 /* Should fail NR_ITERS times */ 20 /* Should fail NR_ITERS times */
21 for (i = 0; i < NR_ITERS; i++) 21 for (i = 0; i < NR_ITERS; i++)
22 epoll_pwait(-(i + 1), NULL, 0, 0, NULL); 22 epoll_wait(-(i + 1), NULL, 0, 0);
23 return 0; 23 return 0;
24} 24}
25 25
@@ -61,7 +61,7 @@ static struct {
61 "[basic_bpf_test]", 61 "[basic_bpf_test]",
62 "fix 'perf test LLVM' first", 62 "fix 'perf test LLVM' first",
63 "load bpf object failed", 63 "load bpf object failed",
64 &epoll_pwait_loop, 64 &epoll_wait_loop,
65 (NR_ITERS + 1) / 2, 65 (NR_ITERS + 1) / 2,
66 }, 66 },
67#ifdef HAVE_BPF_PROLOGUE 67#ifdef HAVE_BPF_PROLOGUE
@@ -143,14 +143,14 @@ static int do_test(struct bpf_object *obj, int (*func)(void),
143 err = perf_evlist__open(evlist); 143 err = perf_evlist__open(evlist);
144 if (err < 0) { 144 if (err < 0) {
145 pr_debug("perf_evlist__open: %s\n", 145 pr_debug("perf_evlist__open: %s\n",
146 strerror_r(errno, sbuf, sizeof(sbuf))); 146 str_error_r(errno, sbuf, sizeof(sbuf)));
147 goto out_delete_evlist; 147 goto out_delete_evlist;
148 } 148 }
149 149
150 err = perf_evlist__mmap(evlist, opts.mmap_pages, false); 150 err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
151 if (err < 0) { 151 if (err < 0) {
152 pr_debug("perf_evlist__mmap: %s\n", 152 pr_debug("perf_evlist__mmap: %s\n",
153 strerror_r(errno, sbuf, sizeof(sbuf))); 153 str_error_r(errno, sbuf, sizeof(sbuf)));
154 goto out_delete_evlist; 154 goto out_delete_evlist;
155 } 155 }
156 156
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 0e95c20ecf6e..10eb30686c9c 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -14,6 +14,8 @@
14#include <subcmd/parse-options.h> 14#include <subcmd/parse-options.h>
15#include "symbol.h" 15#include "symbol.h"
16 16
17static bool dont_fork;
18
17struct test __weak arch_tests[] = { 19struct test __weak arch_tests[] = {
18 { 20 {
19 .func = NULL, 21 .func = NULL,
@@ -212,6 +214,18 @@ static struct test generic_tests[] = {
212 .func = test__backward_ring_buffer, 214 .func = test__backward_ring_buffer,
213 }, 215 },
214 { 216 {
217 .desc = "Test cpu map print",
218 .func = test__cpu_map_print,
219 },
220 {
221 .desc = "Test SDT event probing",
222 .func = test__sdt_event,
223 },
224 {
225 .desc = "Test is_printable_array function",
226 .func = test__is_printable_array,
227 },
228 {
215 .func = NULL, 229 .func = NULL,
216 }, 230 },
217}; 231};
@@ -247,44 +261,51 @@ static bool perf_test__matches(struct test *test, int curr, int argc, const char
247 261
248static int run_test(struct test *test, int subtest) 262static int run_test(struct test *test, int subtest)
249{ 263{
250 int status, err = -1, child = fork(); 264 int status, err = -1, child = dont_fork ? 0 : fork();
251 char sbuf[STRERR_BUFSIZE]; 265 char sbuf[STRERR_BUFSIZE];
252 266
253 if (child < 0) { 267 if (child < 0) {
254 pr_err("failed to fork test: %s\n", 268 pr_err("failed to fork test: %s\n",
255 strerror_r(errno, sbuf, sizeof(sbuf))); 269 str_error_r(errno, sbuf, sizeof(sbuf)));
256 return -1; 270 return -1;
257 } 271 }
258 272
259 if (!child) { 273 if (!child) {
260 pr_debug("test child forked, pid %d\n", getpid()); 274 if (!dont_fork) {
261 if (!verbose) { 275 pr_debug("test child forked, pid %d\n", getpid());
262 int nullfd = open("/dev/null", O_WRONLY); 276
263 if (nullfd >= 0) { 277 if (!verbose) {
264 close(STDERR_FILENO); 278 int nullfd = open("/dev/null", O_WRONLY);
265 close(STDOUT_FILENO); 279
266 280 if (nullfd >= 0) {
267 dup2(nullfd, STDOUT_FILENO); 281 close(STDERR_FILENO);
268 dup2(STDOUT_FILENO, STDERR_FILENO); 282 close(STDOUT_FILENO);
269 close(nullfd); 283
284 dup2(nullfd, STDOUT_FILENO);
285 dup2(STDOUT_FILENO, STDERR_FILENO);
286 close(nullfd);
287 }
288 } else {
289 signal(SIGSEGV, sighandler_dump_stack);
290 signal(SIGFPE, sighandler_dump_stack);
270 } 291 }
271 } else {
272 signal(SIGSEGV, sighandler_dump_stack);
273 signal(SIGFPE, sighandler_dump_stack);
274 } 292 }
275 293
276 err = test->func(subtest); 294 err = test->func(subtest);
277 exit(err); 295 if (!dont_fork)
296 exit(err);
278 } 297 }
279 298
280 wait(&status); 299 if (!dont_fork) {
300 wait(&status);
281 301
282 if (WIFEXITED(status)) { 302 if (WIFEXITED(status)) {
283 err = (signed char)WEXITSTATUS(status); 303 err = (signed char)WEXITSTATUS(status);
284 pr_debug("test child finished with %d\n", err); 304 pr_debug("test child finished with %d\n", err);
285 } else if (WIFSIGNALED(status)) { 305 } else if (WIFSIGNALED(status)) {
286 err = -1; 306 err = -1;
287 pr_debug("test child interrupted\n"); 307 pr_debug("test child interrupted\n");
308 }
288 } 309 }
289 310
290 return err; 311 return err;
@@ -425,6 +446,8 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
425 OPT_STRING('s', "skip", &skip, "tests", "tests to skip"), 446 OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
426 OPT_INCR('v', "verbose", &verbose, 447 OPT_INCR('v', "verbose", &verbose,
427 "be more verbose (show symbol address, etc)"), 448 "be more verbose (show symbol address, etc)"),
449 OPT_BOOLEAN('F', "dont-fork", &dont_fork,
450 "Do not fork for testcase"),
428 OPT_END() 451 OPT_END()
429 }; 452 };
430 const char * const test_subcommands[] = { "list", NULL }; 453 const char * const test_subcommands[] = { "list", NULL };
diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c
index 4cb6418a8ffc..f168a85992d0 100644
--- a/tools/perf/tests/cpumap.c
+++ b/tools/perf/tests/cpumap.c
@@ -1,5 +1,12 @@
1#include "tests.h" 1#include "tests.h"
2#include <stdio.h>
2#include "cpumap.h" 3#include "cpumap.h"
4#include "event.h"
5#include <string.h>
6#include <linux/bitops.h>
7#include "debug.h"
8
9struct machine;
3 10
4static int process_event_mask(struct perf_tool *tool __maybe_unused, 11static int process_event_mask(struct perf_tool *tool __maybe_unused,
5 union perf_event *event, 12 union perf_event *event,
@@ -86,3 +93,27 @@ int test__cpu_map_synthesize(int subtest __maybe_unused)
86 cpu_map__put(cpus); 93 cpu_map__put(cpus);
87 return 0; 94 return 0;
88} 95}
96
97static int cpu_map_print(const char *str)
98{
99 struct cpu_map *map = cpu_map__new(str);
100 char buf[100];
101
102 if (!map)
103 return -1;
104
105 cpu_map__snprint(map, buf, sizeof(buf));
106 return !strcmp(buf, str);
107}
108
109int test__cpu_map_print(int subtest __maybe_unused)
110{
111 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1"));
112 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5"));
113 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3,5,7,9,11,13,15,17,19,21-40"));
114 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("2-5"));
115 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37"));
116 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37"));
117 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1-10,12-20,22-30,32-40"));
118 return 0;
119}
diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c
index 8cf0d9e189a8..13725e09ba22 100644
--- a/tools/perf/tests/dso-data.c
+++ b/tools/perf/tests/dso-data.c
@@ -251,6 +251,9 @@ int test__dso_data_cache(int subtest __maybe_unused)
251 long nr_end, nr = open_files_cnt(); 251 long nr_end, nr = open_files_cnt();
252 int dso_cnt, limit, i, fd; 252 int dso_cnt, limit, i, fd;
253 253
254 /* Rest the internal dso open counter limit. */
255 reset_fd_limit();
256
254 memset(&machine, 0, sizeof(machine)); 257 memset(&machine, 0, sizeof(machine));
255 258
256 /* set as system limit */ 259 /* set as system limit */
@@ -312,6 +315,9 @@ int test__dso_data_reopen(int subtest __maybe_unused)
312#define dso_1 (dsos[1]) 315#define dso_1 (dsos[1])
313#define dso_2 (dsos[2]) 316#define dso_2 (dsos[2])
314 317
318 /* Rest the internal dso open counter limit. */
319 reset_fd_limit();
320
315 memset(&machine, 0, sizeof(machine)); 321 memset(&machine, 0, sizeof(machine));
316 322
317 /* 323 /*
diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c
index 95fb744f6628..19ef77bd6eb4 100644
--- a/tools/perf/tests/event-times.c
+++ b/tools/perf/tests/event-times.c
@@ -37,7 +37,7 @@ static int attach__enable_on_exec(struct perf_evlist *evlist)
37 err = perf_evlist__open(evlist); 37 err = perf_evlist__open(evlist);
38 if (err < 0) { 38 if (err < 0) {
39 pr_debug("perf_evlist__open: %s\n", 39 pr_debug("perf_evlist__open: %s\n",
40 strerror_r(errno, sbuf, sizeof(sbuf))); 40 str_error_r(errno, sbuf, sizeof(sbuf)));
41 return err; 41 return err;
42 } 42 }
43 43
@@ -200,8 +200,7 @@ static int test_times(int (attach)(struct perf_evlist *),
200 count.ena, count.run); 200 count.ena, count.run);
201 201
202out_err: 202out_err:
203 if (evlist) 203 perf_evlist__delete(evlist);
204 perf_evlist__delete(evlist);
205 return !err ? TEST_OK : TEST_FAIL; 204 return !err ? TEST_OK : TEST_FAIL;
206} 205}
207 206
diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c
index 2de4a4f2c3ed..60926a1f6fd7 100644
--- a/tools/perf/tests/evsel-roundtrip-name.c
+++ b/tools/perf/tests/evsel-roundtrip-name.c
@@ -80,7 +80,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)
80 } 80 }
81 81
82 err = 0; 82 err = 0;
83 evlist__for_each(evlist, evsel) { 83 evlist__for_each_entry(evlist, evsel) {
84 if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) { 84 if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
85 --err; 85 --err;
86 pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]); 86 pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c
index c809463edbe5..a2b5ff9bf83d 100644
--- a/tools/perf/tests/fdarray.c
+++ b/tools/perf/tests/fdarray.c
@@ -1,4 +1,5 @@
1#include <api/fd/array.h> 1#include <api/fd/array.h>
2#include <poll.h>
2#include "util/debug.h" 3#include "util/debug.h"
3#include "tests/tests.h" 4#include "tests/tests.h"
4 5
@@ -36,7 +37,7 @@ int test__fdarray__filter(int subtest __maybe_unused)
36 } 37 }
37 38
38 fdarray__init_revents(fda, POLLIN); 39 fdarray__init_revents(fda, POLLIN);
39 nr_fds = fdarray__filter(fda, POLLHUP, NULL); 40 nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
40 if (nr_fds != fda->nr_alloc) { 41 if (nr_fds != fda->nr_alloc) {
41 pr_debug("\nfdarray__filter()=%d != %d shouldn't have filtered anything", 42 pr_debug("\nfdarray__filter()=%d != %d shouldn't have filtered anything",
42 nr_fds, fda->nr_alloc); 43 nr_fds, fda->nr_alloc);
@@ -44,7 +45,7 @@ int test__fdarray__filter(int subtest __maybe_unused)
44 } 45 }
45 46
46 fdarray__init_revents(fda, POLLHUP); 47 fdarray__init_revents(fda, POLLHUP);
47 nr_fds = fdarray__filter(fda, POLLHUP, NULL); 48 nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
48 if (nr_fds != 0) { 49 if (nr_fds != 0) {
49 pr_debug("\nfdarray__filter()=%d != %d, should have filtered all fds", 50 pr_debug("\nfdarray__filter()=%d != %d, should have filtered all fds",
50 nr_fds, fda->nr_alloc); 51 nr_fds, fda->nr_alloc);
@@ -57,7 +58,7 @@ int test__fdarray__filter(int subtest __maybe_unused)
57 58
58 pr_debug("\nfiltering all but fda->entries[2]:"); 59 pr_debug("\nfiltering all but fda->entries[2]:");
59 fdarray__fprintf_prefix(fda, "before", stderr); 60 fdarray__fprintf_prefix(fda, "before", stderr);
60 nr_fds = fdarray__filter(fda, POLLHUP, NULL); 61 nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
61 fdarray__fprintf_prefix(fda, " after", stderr); 62 fdarray__fprintf_prefix(fda, " after", stderr);
62 if (nr_fds != 1) { 63 if (nr_fds != 1) {
63 pr_debug("\nfdarray__filter()=%d != 1, should have left just one event", nr_fds); 64 pr_debug("\nfdarray__filter()=%d != 1, should have left just one event", nr_fds);
@@ -78,7 +79,7 @@ int test__fdarray__filter(int subtest __maybe_unused)
78 79
79 pr_debug("\nfiltering all but (fda->entries[0], fda->entries[3]):"); 80 pr_debug("\nfiltering all but (fda->entries[0], fda->entries[3]):");
80 fdarray__fprintf_prefix(fda, "before", stderr); 81 fdarray__fprintf_prefix(fda, "before", stderr);
81 nr_fds = fdarray__filter(fda, POLLHUP, NULL); 82 nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
82 fdarray__fprintf_prefix(fda, " after", stderr); 83 fdarray__fprintf_prefix(fda, " after", stderr);
83 if (nr_fds != 2) { 84 if (nr_fds != 2) {
84 pr_debug("\nfdarray__filter()=%d != 2, should have left just two events", 85 pr_debug("\nfdarray__filter()=%d != 2, should have left just two events",
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c
index a9e3db3afac4..9fd54b79a788 100644
--- a/tools/perf/tests/hists_cumulate.c
+++ b/tools/perf/tests/hists_cumulate.c
@@ -216,6 +216,8 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec
216 216
217 /* check callchain entries */ 217 /* check callchain entries */
218 root = &he->callchain->node.rb_root; 218 root = &he->callchain->node.rb_root;
219
220 TEST_ASSERT_VAL("callchains expected", !RB_EMPTY_ROOT(root));
219 cnode = rb_entry(rb_first(root), struct callchain_node, rb_node); 221 cnode = rb_entry(rb_first(root), struct callchain_node, rb_node);
220 222
221 c = 0; 223 c = 0;
@@ -666,6 +668,8 @@ static int test4(struct perf_evsel *evsel, struct machine *machine)
666 perf_evsel__set_sample_bit(evsel, CALLCHAIN); 668 perf_evsel__set_sample_bit(evsel, CALLCHAIN);
667 669
668 setup_sorting(NULL); 670 setup_sorting(NULL);
671
672 callchain_param = callchain_param_default;
669 callchain_register_param(&callchain_param); 673 callchain_register_param(&callchain_param);
670 674
671 err = add_hist_entries(hists, machine); 675 err = add_hist_entries(hists, machine);
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c
index e846f8c42013..62efb14f3a5a 100644
--- a/tools/perf/tests/hists_filter.c
+++ b/tools/perf/tests/hists_filter.c
@@ -56,7 +56,7 @@ static int add_hist_entries(struct perf_evlist *evlist,
56 * (perf [perf] main) will be collapsed to an existing entry 56 * (perf [perf] main) will be collapsed to an existing entry
57 * so total 9 entries will be in the tree. 57 * so total 9 entries will be in the tree.
58 */ 58 */
59 evlist__for_each(evlist, evsel) { 59 evlist__for_each_entry(evlist, evsel) {
60 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) { 60 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
61 struct hist_entry_iter iter = { 61 struct hist_entry_iter iter = {
62 .evsel = evsel, 62 .evsel = evsel,
@@ -136,7 +136,7 @@ int test__hists_filter(int subtest __maybe_unused)
136 if (err < 0) 136 if (err < 0)
137 goto out; 137 goto out;
138 138
139 evlist__for_each(evlist, evsel) { 139 evlist__for_each_entry(evlist, evsel) {
140 struct hists *hists = evsel__hists(evsel); 140 struct hists *hists = evsel__hists(evsel);
141 141
142 hists__collapse_resort(hists, NULL); 142 hists__collapse_resort(hists, NULL);
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index acf5a1301c07..eddc7407ff8a 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -72,7 +72,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
72 * However the second evsel also has a collapsed entry for 72 * However the second evsel also has a collapsed entry for
73 * "bash [libc] malloc" so total 9 entries will be in the tree. 73 * "bash [libc] malloc" so total 9 entries will be in the tree.
74 */ 74 */
75 evlist__for_each(evlist, evsel) { 75 evlist__for_each_entry(evlist, evsel) {
76 struct hists *hists = evsel__hists(evsel); 76 struct hists *hists = evsel__hists(evsel);
77 77
78 for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { 78 for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
@@ -84,7 +84,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
84 if (machine__resolve(machine, &al, &sample) < 0) 84 if (machine__resolve(machine, &al, &sample) < 0)
85 goto out; 85 goto out;
86 86
87 he = __hists__add_entry(hists, &al, NULL, 87 he = hists__add_entry(hists, &al, NULL,
88 NULL, NULL, &sample, true); 88 NULL, NULL, &sample, true);
89 if (he == NULL) { 89 if (he == NULL) {
90 addr_location__put(&al); 90 addr_location__put(&al);
@@ -103,7 +103,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
103 if (machine__resolve(machine, &al, &sample) < 0) 103 if (machine__resolve(machine, &al, &sample) < 0)
104 goto out; 104 goto out;
105 105
106 he = __hists__add_entry(hists, &al, NULL, 106 he = hists__add_entry(hists, &al, NULL,
107 NULL, NULL, &sample, true); 107 NULL, NULL, &sample, true);
108 if (he == NULL) { 108 if (he == NULL) {
109 addr_location__put(&al); 109 addr_location__put(&al);
@@ -301,7 +301,7 @@ int test__hists_link(int subtest __maybe_unused)
301 if (err < 0) 301 if (err < 0)
302 goto out; 302 goto out;
303 303
304 evlist__for_each(evlist, evsel) { 304 evlist__for_each_entry(evlist, evsel) {
305 hists = evsel__hists(evsel); 305 hists = evsel__hists(evsel);
306 hists__collapse_resort(hists, NULL); 306 hists__collapse_resort(hists, NULL);
307 307
diff --git a/tools/perf/tests/is_printable_array.c b/tools/perf/tests/is_printable_array.c
new file mode 100644
index 000000000000..42e13393e502
--- /dev/null
+++ b/tools/perf/tests/is_printable_array.c
@@ -0,0 +1,36 @@
1#include <linux/compiler.h>
2#include "tests.h"
3#include "debug.h"
4#include "util.h"
5
6int test__is_printable_array(int subtest __maybe_unused)
7{
8 char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 };
9 char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 };
10 struct {
11 char *buf;
12 unsigned int len;
13 int ret;
14 } t[] = {
15 { (char *) "krava", sizeof("krava"), 1 },
16 { (char *) "krava", sizeof("krava") - 1, 0 },
17 { (char *) "", sizeof(""), 1 },
18 { (char *) "", 0, 0 },
19 { NULL, 0, 0 },
20 { buf1, sizeof(buf1), 0 },
21 { buf2, sizeof(buf2), 0 },
22 };
23 unsigned int i;
24
25 for (i = 0; i < ARRAY_SIZE(t); i++) {
26 int ret;
27
28 ret = is_printable_array((char *) t[i].buf, t[i].len);
29 if (ret != t[i].ret) {
30 pr_err("failed: test %u\n", i);
31 return TEST_FAIL;
32 }
33 }
34
35 return TEST_OK;
36}
diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c
index d2af78193153..76f41f249944 100644
--- a/tools/perf/tests/kmod-path.c
+++ b/tools/perf/tests/kmod-path.c
@@ -1,4 +1,5 @@
1#include <stdbool.h> 1#include <stdbool.h>
2#include <stdlib.h>
2#include "tests.h" 3#include "tests.h"
3#include "dso.h" 4#include "dso.h"
4#include "debug.h" 5#include "debug.h"
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index cff564fb4b66..b798a4bfd238 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -5,6 +5,7 @@
5#include "llvm.h" 5#include "llvm.h"
6#include "tests.h" 6#include "tests.h"
7#include "debug.h" 7#include "debug.h"
8#include "util.h"
8 9
9#ifdef HAVE_LIBBPF_SUPPORT 10#ifdef HAVE_LIBBPF_SUPPORT
10static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) 11static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index cac15d93aea6..143f4d549769 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -81,6 +81,8 @@ make_no_libbionic := NO_LIBBIONIC=1
81make_no_auxtrace := NO_AUXTRACE=1 81make_no_auxtrace := NO_AUXTRACE=1
82make_no_libbpf := NO_LIBBPF=1 82make_no_libbpf := NO_LIBBPF=1
83make_no_libcrypto := NO_LIBCRYPTO=1 83make_no_libcrypto := NO_LIBCRYPTO=1
84make_with_babeltrace:= LIBBABELTRACE=1
85make_no_sdt := NO_SDT=1
84make_tags := tags 86make_tags := tags
85make_cscope := cscope 87make_cscope := cscope
86make_help := help 88make_help := help
@@ -104,7 +106,7 @@ make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
104make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 106make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
105make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 107make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
106make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 108make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
107make_minimal += NO_LIBCRYPTO=1 109make_minimal += NO_LIBCRYPTO=1 NO_SDT=1
108 110
109# $(run) contains all available tests 111# $(run) contains all available tests
110run := make_pure 112run := make_pure
@@ -136,6 +138,7 @@ run += make_no_libaudit
136run += make_no_libbionic 138run += make_no_libbionic
137run += make_no_auxtrace 139run += make_no_auxtrace
138run += make_no_libbpf 140run += make_no_libbpf
141run += make_with_babeltrace
139run += make_help 142run += make_help
140run += make_doc 143run += make_doc
141run += make_perf_o 144run += make_perf_o
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 359e98fcd94c..634bce9caebd 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -1,3 +1,6 @@
1/* For the CLR_() macros */
2#include <pthread.h>
3
1#include "evlist.h" 4#include "evlist.h"
2#include "evsel.h" 5#include "evsel.h"
3#include "thread_map.h" 6#include "thread_map.h"
@@ -49,7 +52,7 @@ int test__basic_mmap(int subtest __maybe_unused)
49 sched_setaffinity(0, sizeof(cpu_set), &cpu_set); 52 sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
50 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { 53 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
51 pr_debug("sched_setaffinity() failed on CPU %d: %s ", 54 pr_debug("sched_setaffinity() failed on CPU %d: %s ",
52 cpus->map[0], strerror_r(errno, sbuf, sizeof(sbuf))); 55 cpus->map[0], str_error_r(errno, sbuf, sizeof(sbuf)));
53 goto out_free_cpus; 56 goto out_free_cpus;
54 } 57 }
55 58
@@ -79,7 +82,7 @@ int test__basic_mmap(int subtest __maybe_unused)
79 if (perf_evsel__open(evsels[i], cpus, threads) < 0) { 82 if (perf_evsel__open(evsels[i], cpus, threads) < 0) {
80 pr_debug("failed to open counter: %s, " 83 pr_debug("failed to open counter: %s, "
81 "tweak /proc/sys/kernel/perf_event_paranoid?\n", 84 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
82 strerror_r(errno, sbuf, sizeof(sbuf))); 85 str_error_r(errno, sbuf, sizeof(sbuf)));
83 goto out_delete_evlist; 86 goto out_delete_evlist;
84 } 87 }
85 88
@@ -89,7 +92,7 @@ int test__basic_mmap(int subtest __maybe_unused)
89 92
90 if (perf_evlist__mmap(evlist, 128, true) < 0) { 93 if (perf_evlist__mmap(evlist, 128, true) < 0) {
91 pr_debug("failed to mmap events: %d (%s)\n", errno, 94 pr_debug("failed to mmap events: %d (%s)\n", errno,
92 strerror_r(errno, sbuf, sizeof(sbuf))); 95 str_error_r(errno, sbuf, sizeof(sbuf)));
93 goto out_delete_evlist; 96 goto out_delete_evlist;
94 } 97 }
95 98
@@ -126,7 +129,7 @@ int test__basic_mmap(int subtest __maybe_unused)
126 } 129 }
127 130
128 err = 0; 131 err = 0;
129 evlist__for_each(evlist, evsel) { 132 evlist__for_each_entry(evlist, evsel) {
130 if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { 133 if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
131 pr_debug("expected %d %s events, got %d\n", 134 pr_debug("expected %d %s events, got %d\n",
132 expected_nr_events[evsel->idx], 135 expected_nr_events[evsel->idx],
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index ad1cb63139a7..c8d9592eb142 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -1,3 +1,6 @@
1/* For the CPU_* macros */
2#include <pthread.h>
3
1#include <api/fs/fs.h> 4#include <api/fs/fs.h>
2#include <linux/err.h> 5#include <linux/err.h>
3#include "evsel.h" 6#include "evsel.h"
@@ -41,7 +44,7 @@ int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused)
41 if (perf_evsel__open(evsel, cpus, threads) < 0) { 44 if (perf_evsel__open(evsel, cpus, threads) < 0) {
42 pr_debug("failed to open counter: %s, " 45 pr_debug("failed to open counter: %s, "
43 "tweak /proc/sys/kernel/perf_event_paranoid?\n", 46 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
44 strerror_r(errno, sbuf, sizeof(sbuf))); 47 str_error_r(errno, sbuf, sizeof(sbuf)));
45 goto out_evsel_delete; 48 goto out_evsel_delete;
46 } 49 }
47 50
@@ -62,7 +65,7 @@ int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused)
62 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { 65 if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
63 pr_debug("sched_setaffinity() failed on CPU %d: %s ", 66 pr_debug("sched_setaffinity() failed on CPU %d: %s ",
64 cpus->map[cpu], 67 cpus->map[cpu],
65 strerror_r(errno, sbuf, sizeof(sbuf))); 68 str_error_r(errno, sbuf, sizeof(sbuf)));
66 goto out_close_fd; 69 goto out_close_fd;
67 } 70 }
68 for (i = 0; i < ncalls; ++i) { 71 for (i = 0; i < ncalls; ++i) {
diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c
index 4344fe482c1d..f52239fed361 100644
--- a/tools/perf/tests/openat-syscall-tp-fields.c
+++ b/tools/perf/tests/openat-syscall-tp-fields.c
@@ -6,6 +6,13 @@
6#include "tests.h" 6#include "tests.h"
7#include "debug.h" 7#include "debug.h"
8 8
9#ifndef O_DIRECTORY
10#define O_DIRECTORY 00200000
11#endif
12#ifndef AT_FDCWD
13#define AT_FDCWD -100
14#endif
15
9int test__syscall_openat_tp_fields(int subtest __maybe_unused) 16int test__syscall_openat_tp_fields(int subtest __maybe_unused)
10{ 17{
11 struct record_opts opts = { 18 struct record_opts opts = {
@@ -51,14 +58,14 @@ int test__syscall_openat_tp_fields(int subtest __maybe_unused)
51 err = perf_evlist__open(evlist); 58 err = perf_evlist__open(evlist);
52 if (err < 0) { 59 if (err < 0) {
53 pr_debug("perf_evlist__open: %s\n", 60 pr_debug("perf_evlist__open: %s\n",
54 strerror_r(errno, sbuf, sizeof(sbuf))); 61 str_error_r(errno, sbuf, sizeof(sbuf)));
55 goto out_delete_evlist; 62 goto out_delete_evlist;
56 } 63 }
57 64
58 err = perf_evlist__mmap(evlist, UINT_MAX, false); 65 err = perf_evlist__mmap(evlist, UINT_MAX, false);
59 if (err < 0) { 66 if (err < 0) {
60 pr_debug("perf_evlist__mmap: %s\n", 67 pr_debug("perf_evlist__mmap: %s\n",
61 strerror_r(errno, sbuf, sizeof(sbuf))); 68 str_error_r(errno, sbuf, sizeof(sbuf)));
62 goto out_delete_evlist; 69 goto out_delete_evlist;
63 } 70 }
64 71
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index 1184f9ba6499..d7414128d7fe 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -29,7 +29,7 @@ int test__openat_syscall_event(int subtest __maybe_unused)
29 if (perf_evsel__open_per_thread(evsel, threads) < 0) { 29 if (perf_evsel__open_per_thread(evsel, threads) < 0) {
30 pr_debug("failed to open counter: %s, " 30 pr_debug("failed to open counter: %s, "
31 "tweak /proc/sys/kernel/perf_event_paranoid?\n", 31 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
32 strerror_r(errno, sbuf, sizeof(sbuf))); 32 str_error_r(errno, sbuf, sizeof(sbuf)));
33 goto out_evsel_delete; 33 goto out_evsel_delete;
34 } 34 }
35 35
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 7865f68dc0d8..20c2e641c422 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -32,7 +32,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
32 TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); 32 TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
33 TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); 33 TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups);
34 34
35 evlist__for_each(evlist, evsel) { 35 evlist__for_each_entry(evlist, evsel) {
36 TEST_ASSERT_VAL("wrong type", 36 TEST_ASSERT_VAL("wrong type",
37 PERF_TYPE_TRACEPOINT == evsel->attr.type); 37 PERF_TYPE_TRACEPOINT == evsel->attr.type);
38 TEST_ASSERT_VAL("wrong sample_type", 38 TEST_ASSERT_VAL("wrong sample_type",
@@ -207,7 +207,7 @@ test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist)
207 207
208 TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); 208 TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
209 209
210 evlist__for_each(evlist, evsel) { 210 evlist__for_each_entry(evlist, evsel) {
211 TEST_ASSERT_VAL("wrong exclude_user", 211 TEST_ASSERT_VAL("wrong exclude_user",
212 !evsel->attr.exclude_user); 212 !evsel->attr.exclude_user);
213 TEST_ASSERT_VAL("wrong exclude_kernel", 213 TEST_ASSERT_VAL("wrong exclude_kernel",
@@ -1783,8 +1783,8 @@ static int test_pmu_events(void)
1783 struct evlist_test e; 1783 struct evlist_test e;
1784 char name[MAX_NAME]; 1784 char name[MAX_NAME];
1785 1785
1786 if (!strcmp(ent->d_name, ".") || 1786 /* Names containing . are special and cannot be used directly */
1787 !strcmp(ent->d_name, "..")) 1787 if (strchr(ent->d_name, '.'))
1788 continue; 1788 continue;
1789 1789
1790 snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name); 1790 snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name);
diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c
index 294c76b01b41..81c6eeaca0f5 100644
--- a/tools/perf/tests/parse-no-sample-id-all.c
+++ b/tools/perf/tests/parse-no-sample-id-all.c
@@ -44,8 +44,7 @@ static int process_events(union perf_event **events, size_t count)
44 for (i = 0; i < count && !err; i++) 44 for (i = 0; i < count && !err; i++)
45 err = process_event(&evlist, events[i]); 45 err = process_event(&evlist, events[i]);
46 46
47 if (evlist) 47 perf_evlist__delete(evlist);
48 perf_evlist__delete(evlist);
49 48
50 return err; 49 return err;
51} 50}
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index b836ee6a8d9b..8f2e1de6d0ea 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -1,3 +1,6 @@
1/* For the CLR_() macros */
2#include <pthread.h>
3
1#include <sched.h> 4#include <sched.h>
2#include "evlist.h" 5#include "evlist.h"
3#include "evsel.h" 6#include "evsel.h"
@@ -104,7 +107,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)
104 err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask); 107 err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
105 if (err < 0) { 108 if (err < 0) {
106 pr_debug("sched__get_first_possible_cpu: %s\n", 109 pr_debug("sched__get_first_possible_cpu: %s\n",
107 strerror_r(errno, sbuf, sizeof(sbuf))); 110 str_error_r(errno, sbuf, sizeof(sbuf)));
108 goto out_delete_evlist; 111 goto out_delete_evlist;
109 } 112 }
110 113
@@ -115,7 +118,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)
115 */ 118 */
116 if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) { 119 if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) {
117 pr_debug("sched_setaffinity: %s\n", 120 pr_debug("sched_setaffinity: %s\n",
118 strerror_r(errno, sbuf, sizeof(sbuf))); 121 str_error_r(errno, sbuf, sizeof(sbuf)));
119 goto out_delete_evlist; 122 goto out_delete_evlist;
120 } 123 }
121 124
@@ -126,7 +129,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)
126 err = perf_evlist__open(evlist); 129 err = perf_evlist__open(evlist);
127 if (err < 0) { 130 if (err < 0) {
128 pr_debug("perf_evlist__open: %s\n", 131 pr_debug("perf_evlist__open: %s\n",
129 strerror_r(errno, sbuf, sizeof(sbuf))); 132 str_error_r(errno, sbuf, sizeof(sbuf)));
130 goto out_delete_evlist; 133 goto out_delete_evlist;
131 } 134 }
132 135
@@ -138,7 +141,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)
138 err = perf_evlist__mmap(evlist, opts.mmap_pages, false); 141 err = perf_evlist__mmap(evlist, opts.mmap_pages, false);
139 if (err < 0) { 142 if (err < 0) {
140 pr_debug("perf_evlist__mmap: %s\n", 143 pr_debug("perf_evlist__mmap: %s\n",
141 strerror_r(errno, sbuf, sizeof(sbuf))); 144 str_error_r(errno, sbuf, sizeof(sbuf)));
142 goto out_delete_evlist; 145 goto out_delete_evlist;
143 } 146 }
144 147
diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c
new file mode 100644
index 000000000000..f59d210e1baf
--- /dev/null
+++ b/tools/perf/tests/sdt.c
@@ -0,0 +1,115 @@
1#include <stdio.h>
2#include <sys/epoll.h>
3#include <util/util.h>
4#include <util/evlist.h>
5#include <linux/filter.h>
6#include "tests.h"
7#include "debug.h"
8#include "probe-file.h"
9#include "build-id.h"
10
11/* To test SDT event, we need libelf support to scan elf binary */
12#if defined(HAVE_SDT_EVENT) && defined(HAVE_LIBELF_SUPPORT)
13
14#include <sys/sdt.h>
15
16static int target_function(void)
17{
18 DTRACE_PROBE(perf, test_target);
19 return TEST_OK;
20}
21
22/* Copied from builtin-buildid-cache.c */
23static int build_id_cache__add_file(const char *filename)
24{
25 char sbuild_id[SBUILD_ID_SIZE];
26 u8 build_id[BUILD_ID_SIZE];
27 int err;
28
29 err = filename__read_build_id(filename, &build_id, sizeof(build_id));
30 if (err < 0) {
31 pr_debug("Failed to read build id of %s\n", filename);
32 return err;
33 }
34
35 build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
36 err = build_id_cache__add_s(sbuild_id, filename, false, false);
37 if (err < 0)
38 pr_debug("Failed to add build id cache of %s\n", filename);
39 return err;
40}
41
42static char *get_self_path(void)
43{
44 char *buf = calloc(PATH_MAX, sizeof(char));
45
46 if (buf && readlink("/proc/self/exe", buf, PATH_MAX) < 0) {
47 pr_debug("Failed to get correct path of perf\n");
48 free(buf);
49 return NULL;
50 }
51 return buf;
52}
53
54static int search_cached_probe(const char *target,
55 const char *group, const char *event)
56{
57 struct probe_cache *cache = probe_cache__new(target);
58 int ret = 0;
59
60 if (!cache) {
61 pr_debug("Failed to open probe cache of %s\n", target);
62 return -EINVAL;
63 }
64
65 if (!probe_cache__find_by_name(cache, group, event)) {
66 pr_debug("Failed to find %s:%s in the cache\n", group, event);
67 ret = -ENOENT;
68 }
69 probe_cache__delete(cache);
70
71 return ret;
72}
73
74int test__sdt_event(int subtests __maybe_unused)
75{
76 int ret = TEST_FAIL;
77 char __tempdir[] = "./test-buildid-XXXXXX";
78 char *tempdir = NULL, *myself = get_self_path();
79
80 if (myself == NULL || mkdtemp(__tempdir) == NULL) {
81 pr_debug("Failed to make a tempdir for build-id cache\n");
82 goto error;
83 }
84 /* Note that buildid_dir must be an absolute path */
85 tempdir = realpath(__tempdir, NULL);
86
87 /* At first, scan itself */
88 set_buildid_dir(tempdir);
89 if (build_id_cache__add_file(myself) < 0)
90 goto error_rmdir;
91
92 /* Open a cache and make sure the SDT is stored */
93 if (search_cached_probe(myself, "sdt_perf", "test_target") < 0)
94 goto error_rmdir;
95
96 /* TBD: probing on the SDT event and collect logs */
97
98 /* Call the target and get an event */
99 ret = target_function();
100
101error_rmdir:
102 /* Cleanup temporary buildid dir */
103 rm_rf(tempdir);
104error:
105 free(tempdir);
106 free(myself);
107 return ret;
108}
109#else
110int test__sdt_event(int subtests __maybe_unused)
111{
112 pr_debug("Skip SDT event test because SDT support is not compiled\n");
113 return TEST_SKIP;
114}
115#endif
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 36e8ce1550e3..4c9fd046d57b 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -70,7 +70,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
70 70
71 err = -errno; 71 err = -errno;
72 pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n", 72 pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",
73 strerror_r(errno, sbuf, sizeof(sbuf)), 73 str_error_r(errno, sbuf, sizeof(sbuf)),
74 knob, (u64)attr.sample_freq); 74 knob, (u64)attr.sample_freq);
75 goto out_delete_evlist; 75 goto out_delete_evlist;
76 } 76 }
@@ -78,7 +78,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
78 err = perf_evlist__mmap(evlist, 128, true); 78 err = perf_evlist__mmap(evlist, 128, true);
79 if (err < 0) { 79 if (err < 0) {
80 pr_debug("failed to mmap event: %d (%s)\n", errno, 80 pr_debug("failed to mmap event: %d (%s)\n", errno,
81 strerror_r(errno, sbuf, sizeof(sbuf))); 81 str_error_r(errno, sbuf, sizeof(sbuf)));
82 goto out_delete_evlist; 82 goto out_delete_evlist;
83 } 83 }
84 84
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index 39a689bf7574..7ddbe267d0ac 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -432,7 +432,7 @@ int test__switch_tracking(int subtest __maybe_unused)
432 } 432 }
433 433
434 /* Check non-tracking events are not tracking */ 434 /* Check non-tracking events are not tracking */
435 evlist__for_each(evlist, evsel) { 435 evlist__for_each_entry(evlist, evsel) {
436 if (evsel != tracking_evsel) { 436 if (evsel != tracking_evsel) {
437 if (evsel->attr.mmap || evsel->attr.comm) { 437 if (evsel->attr.mmap || evsel->attr.comm) {
438 pr_debug("Non-tracking event is tracking\n"); 438 pr_debug("Non-tracking event is tracking\n");
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 2dfff7ac8ef3..01a5ba2788c6 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -91,13 +91,13 @@ int test__task_exit(int subtest __maybe_unused)
91 err = perf_evlist__open(evlist); 91 err = perf_evlist__open(evlist);
92 if (err < 0) { 92 if (err < 0) {
93 pr_debug("Couldn't open the evlist: %s\n", 93 pr_debug("Couldn't open the evlist: %s\n",
94 strerror_r(-err, sbuf, sizeof(sbuf))); 94 str_error_r(-err, sbuf, sizeof(sbuf)));
95 goto out_delete_evlist; 95 goto out_delete_evlist;
96 } 96 }
97 97
98 if (perf_evlist__mmap(evlist, 128, true) < 0) { 98 if (perf_evlist__mmap(evlist, 128, true) < 0) {
99 pr_debug("failed to mmap events: %d (%s)\n", errno, 99 pr_debug("failed to mmap events: %d (%s)\n", errno,
100 strerror_r(errno, sbuf, sizeof(sbuf))); 100 str_error_r(errno, sbuf, sizeof(sbuf)));
101 goto out_delete_evlist; 101 goto out_delete_evlist;
102 } 102 }
103 103
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index c57e72c826d2..9bfc0e06c61a 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -87,6 +87,9 @@ int test__synthesize_stat_round(int subtest);
87int test__event_update(int subtest); 87int test__event_update(int subtest);
88int test__event_times(int subtest); 88int test__event_times(int subtest);
89int test__backward_ring_buffer(int subtest); 89int test__backward_ring_buffer(int subtest);
90int test__cpu_map_print(int subtest);
91int test__sdt_event(int subtest);
92int test__is_printable_array(int subtest);
90 93
91#if defined(__arm__) || defined(__aarch64__) 94#if defined(__arm__) || defined(__aarch64__)
92#ifdef HAVE_DWARF_UNWIND_SUPPORT 95#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c
index fccde848fe9c..cee2a2cdc933 100644
--- a/tools/perf/tests/thread-map.c
+++ b/tools/perf/tests/thread-map.c
@@ -1,13 +1,20 @@
1#include <sys/types.h> 1#include <sys/types.h>
2#include <unistd.h> 2#include <unistd.h>
3#include <sys/prctl.h>
3#include "tests.h" 4#include "tests.h"
4#include "thread_map.h" 5#include "thread_map.h"
5#include "debug.h" 6#include "debug.h"
6 7
8#define NAME (const char *) "perf"
9#define NAMEUL (unsigned long) NAME
10
7int test__thread_map(int subtest __maybe_unused) 11int test__thread_map(int subtest __maybe_unused)
8{ 12{
9 struct thread_map *map; 13 struct thread_map *map;
10 14
15 TEST_ASSERT_VAL("failed to set process name",
16 !prctl(PR_SET_NAME, NAMEUL, 0, 0, 0));
17
11 /* test map on current pid */ 18 /* test map on current pid */
12 map = thread_map__new_by_pid(getpid()); 19 map = thread_map__new_by_pid(getpid());
13 TEST_ASSERT_VAL("failed to alloc map", map); 20 TEST_ASSERT_VAL("failed to alloc map", map);
@@ -19,7 +26,7 @@ int test__thread_map(int subtest __maybe_unused)
19 thread_map__pid(map, 0) == getpid()); 26 thread_map__pid(map, 0) == getpid());
20 TEST_ASSERT_VAL("wrong comm", 27 TEST_ASSERT_VAL("wrong comm",
21 thread_map__comm(map, 0) && 28 thread_map__comm(map, 0) &&
22 !strcmp(thread_map__comm(map, 0), "perf")); 29 !strcmp(thread_map__comm(map, 0), NAME));
23 TEST_ASSERT_VAL("wrong refcnt", 30 TEST_ASSERT_VAL("wrong refcnt",
24 atomic_read(&map->refcnt) == 1); 31 atomic_read(&map->refcnt) == 1);
25 thread_map__put(map); 32 thread_map__put(map);
@@ -51,7 +58,7 @@ static int process_event(struct perf_tool *tool __maybe_unused,
51 58
52 TEST_ASSERT_VAL("wrong nr", map->nr == 1); 59 TEST_ASSERT_VAL("wrong nr", map->nr == 1);
53 TEST_ASSERT_VAL("wrong pid", map->entries[0].pid == (u64) getpid()); 60 TEST_ASSERT_VAL("wrong pid", map->entries[0].pid == (u64) getpid());
54 TEST_ASSERT_VAL("wrong comm", !strcmp(map->entries[0].comm, "perf")); 61 TEST_ASSERT_VAL("wrong comm", !strcmp(map->entries[0].comm, NAME));
55 62
56 threads = thread_map__new_event(&event->thread_map); 63 threads = thread_map__new_event(&event->thread_map);
57 TEST_ASSERT_VAL("failed to alloc map", threads); 64 TEST_ASSERT_VAL("failed to alloc map", threads);
@@ -61,7 +68,7 @@ static int process_event(struct perf_tool *tool __maybe_unused,
61 thread_map__pid(threads, 0) == getpid()); 68 thread_map__pid(threads, 0) == getpid());
62 TEST_ASSERT_VAL("wrong comm", 69 TEST_ASSERT_VAL("wrong comm",
63 thread_map__comm(threads, 0) && 70 thread_map__comm(threads, 0) &&
64 !strcmp(thread_map__comm(threads, 0), "perf")); 71 !strcmp(thread_map__comm(threads, 0), NAME));
65 TEST_ASSERT_VAL("wrong refcnt", 72 TEST_ASSERT_VAL("wrong refcnt",
66 atomic_read(&threads->refcnt) == 1); 73 atomic_read(&threads->refcnt) == 1);
67 thread_map__put(threads); 74 thread_map__put(threads);
@@ -72,6 +79,9 @@ int test__thread_map_synthesize(int subtest __maybe_unused)
72{ 79{
73 struct thread_map *threads; 80 struct thread_map *threads;
74 81
82 TEST_ASSERT_VAL("failed to set process name",
83 !prctl(PR_SET_NAME, NAMEUL, 0, 0, 0));
84
75 /* test map on current pid */ 85 /* test map on current pid */
76 threads = thread_map__new_by_pid(getpid()); 86 threads = thread_map__new_by_pid(getpid());
77 TEST_ASSERT_VAL("failed to alloc map", threads); 87 TEST_ASSERT_VAL("failed to alloc map", threads);
diff --git a/tools/perf/trace/beauty/eventfd.c b/tools/perf/trace/beauty/eventfd.c
index d64f4a9128a1..b08f21eb6f4d 100644
--- a/tools/perf/trace/beauty/eventfd.c
+++ b/tools/perf/trace/beauty/eventfd.c
@@ -1,5 +1,3 @@
1#include <sys/eventfd.h>
2
3#ifndef EFD_SEMAPHORE 1#ifndef EFD_SEMAPHORE
4#define EFD_SEMAPHORE 1 2#define EFD_SEMAPHORE 1
5#endif 3#endif
diff --git a/tools/perf/trace/beauty/flock.c b/tools/perf/trace/beauty/flock.c
index 021bb48c6336..74613703a14e 100644
--- a/tools/perf/trace/beauty/flock.c
+++ b/tools/perf/trace/beauty/flock.c
@@ -1,3 +1,20 @@
1#include <fcntl.h>
2
3#ifndef LOCK_MAND
4#define LOCK_MAND 32
5#endif
6
7#ifndef LOCK_READ
8#define LOCK_READ 64
9#endif
10
11#ifndef LOCK_WRITE
12#define LOCK_WRITE 128
13#endif
14
15#ifndef LOCK_RW
16#define LOCK_RW 192
17#endif
1 18
2static size_t syscall_arg__scnprintf_flock(char *bf, size_t size, 19static size_t syscall_arg__scnprintf_flock(char *bf, size_t size,
3 struct syscall_arg *arg) 20 struct syscall_arg *arg)
diff --git a/tools/perf/trace/beauty/futex_op.c b/tools/perf/trace/beauty/futex_op.c
index e2476211f22d..bfd3359b09b6 100644
--- a/tools/perf/trace/beauty/futex_op.c
+++ b/tools/perf/trace/beauty/futex_op.c
@@ -1,5 +1,21 @@
1#include <linux/futex.h> 1#include <linux/futex.h>
2 2
3#ifndef FUTEX_WAIT_BITSET
4#define FUTEX_WAIT_BITSET 9
5#endif
6#ifndef FUTEX_WAKE_BITSET
7#define FUTEX_WAKE_BITSET 10
8#endif
9#ifndef FUTEX_WAIT_REQUEUE_PI
10#define FUTEX_WAIT_REQUEUE_PI 11
11#endif
12#ifndef FUTEX_CMP_REQUEUE_PI
13#define FUTEX_CMP_REQUEUE_PI 12
14#endif
15#ifndef FUTEX_CLOCK_REALTIME
16#define FUTEX_CLOCK_REALTIME 256
17#endif
18
3static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg) 19static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg)
4{ 20{
5 enum syscall_futex_args { 21 enum syscall_futex_args {
diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c
index 3444a4d5382d..d0a3a8e402e7 100644
--- a/tools/perf/trace/beauty/mmap.c
+++ b/tools/perf/trace/beauty/mmap.c
@@ -1,5 +1,9 @@
1#include <sys/mman.h> 1#include <sys/mman.h>
2 2
3#ifndef PROT_SEM
4#define PROT_SEM 0x8
5#endif
6
3static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, 7static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
4 struct syscall_arg *arg) 8 struct syscall_arg *arg)
5{ 9{
@@ -16,9 +20,7 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
16 P_MMAP_PROT(EXEC); 20 P_MMAP_PROT(EXEC);
17 P_MMAP_PROT(READ); 21 P_MMAP_PROT(READ);
18 P_MMAP_PROT(WRITE); 22 P_MMAP_PROT(WRITE);
19#ifdef PROT_SEM
20 P_MMAP_PROT(SEM); 23 P_MMAP_PROT(SEM);
21#endif
22 P_MMAP_PROT(GROWSDOWN); 24 P_MMAP_PROT(GROWSDOWN);
23 P_MMAP_PROT(GROWSUP); 25 P_MMAP_PROT(GROWSUP);
24#undef P_MMAP_PROT 26#undef P_MMAP_PROT
@@ -31,10 +33,31 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
31 33
32#define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot 34#define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot
33 35
36#ifndef MAP_FIXED
37#define MAP_FIXED 0x10
38#endif
39
40#ifndef MAP_ANONYMOUS
41#define MAP_ANONYMOUS 0x20
42#endif
43
44#ifndef MAP_32BIT
45#define MAP_32BIT 0x40
46#endif
47
34#ifndef MAP_STACK 48#ifndef MAP_STACK
35# define MAP_STACK 0x20000 49#define MAP_STACK 0x20000
36#endif 50#endif
37 51
52#ifndef MAP_HUGETLB
53#define MAP_HUGETLB 0x40000
54#endif
55
56#ifndef MAP_UNINITIALIZED
57#define MAP_UNINITIALIZED 0x4000000
58#endif
59
60
38static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, 61static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
39 struct syscall_arg *arg) 62 struct syscall_arg *arg)
40{ 63{
@@ -48,26 +71,20 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
48 71
49 P_MMAP_FLAG(SHARED); 72 P_MMAP_FLAG(SHARED);
50 P_MMAP_FLAG(PRIVATE); 73 P_MMAP_FLAG(PRIVATE);
51#ifdef MAP_32BIT
52 P_MMAP_FLAG(32BIT); 74 P_MMAP_FLAG(32BIT);
53#endif
54 P_MMAP_FLAG(ANONYMOUS); 75 P_MMAP_FLAG(ANONYMOUS);
55 P_MMAP_FLAG(DENYWRITE); 76 P_MMAP_FLAG(DENYWRITE);
56 P_MMAP_FLAG(EXECUTABLE); 77 P_MMAP_FLAG(EXECUTABLE);
57 P_MMAP_FLAG(FILE); 78 P_MMAP_FLAG(FILE);
58 P_MMAP_FLAG(FIXED); 79 P_MMAP_FLAG(FIXED);
59 P_MMAP_FLAG(GROWSDOWN); 80 P_MMAP_FLAG(GROWSDOWN);
60#ifdef MAP_HUGETLB
61 P_MMAP_FLAG(HUGETLB); 81 P_MMAP_FLAG(HUGETLB);
62#endif
63 P_MMAP_FLAG(LOCKED); 82 P_MMAP_FLAG(LOCKED);
64 P_MMAP_FLAG(NONBLOCK); 83 P_MMAP_FLAG(NONBLOCK);
65 P_MMAP_FLAG(NORESERVE); 84 P_MMAP_FLAG(NORESERVE);
66 P_MMAP_FLAG(POPULATE); 85 P_MMAP_FLAG(POPULATE);
67 P_MMAP_FLAG(STACK); 86 P_MMAP_FLAG(STACK);
68#ifdef MAP_UNINITIALIZED
69 P_MMAP_FLAG(UNINITIALIZED); 87 P_MMAP_FLAG(UNINITIALIZED);
70#endif
71#undef P_MMAP_FLAG 88#undef P_MMAP_FLAG
72 89
73 if (flags) 90 if (flags)
@@ -78,6 +95,13 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
78 95
79#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags 96#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
80 97
98#ifndef MREMAP_MAYMOVE
99#define MREMAP_MAYMOVE 1
100#endif
101#ifndef MREMAP_FIXED
102#define MREMAP_FIXED 2
103#endif
104
81static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size, 105static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
82 struct syscall_arg *arg) 106 struct syscall_arg *arg)
83{ 107{
@@ -90,9 +114,7 @@ static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
90 } 114 }
91 115
92 P_MREMAP_FLAG(MAYMOVE); 116 P_MREMAP_FLAG(MAYMOVE);
93#ifdef MREMAP_FIXED
94 P_MREMAP_FLAG(FIXED); 117 P_MREMAP_FLAG(FIXED);
95#endif
96#undef P_MREMAP_FLAG 118#undef P_MREMAP_FLAG
97 119
98 if (flags) 120 if (flags)
@@ -107,6 +129,10 @@ static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
107#define MADV_HWPOISON 100 129#define MADV_HWPOISON 100
108#endif 130#endif
109 131
132#ifndef MADV_SOFT_OFFLINE
133#define MADV_SOFT_OFFLINE 101
134#endif
135
110#ifndef MADV_MERGEABLE 136#ifndef MADV_MERGEABLE
111#define MADV_MERGEABLE 12 137#define MADV_MERGEABLE 12
112#endif 138#endif
@@ -115,6 +141,23 @@ static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
115#define MADV_UNMERGEABLE 13 141#define MADV_UNMERGEABLE 13
116#endif 142#endif
117 143
144#ifndef MADV_HUGEPAGE
145#define MADV_HUGEPAGE 14
146#endif
147
148#ifndef MADV_NOHUGEPAGE
149#define MADV_NOHUGEPAGE 15
150#endif
151
152#ifndef MADV_DONTDUMP
153#define MADV_DONTDUMP 16
154#endif
155
156#ifndef MADV_DODUMP
157#define MADV_DODUMP 17
158#endif
159
160
118static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, 161static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
119 struct syscall_arg *arg) 162 struct syscall_arg *arg)
120{ 163{
@@ -131,24 +174,14 @@ static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
131 P_MADV_BHV(DONTFORK); 174 P_MADV_BHV(DONTFORK);
132 P_MADV_BHV(DOFORK); 175 P_MADV_BHV(DOFORK);
133 P_MADV_BHV(HWPOISON); 176 P_MADV_BHV(HWPOISON);
134#ifdef MADV_SOFT_OFFLINE
135 P_MADV_BHV(SOFT_OFFLINE); 177 P_MADV_BHV(SOFT_OFFLINE);
136#endif
137 P_MADV_BHV(MERGEABLE); 178 P_MADV_BHV(MERGEABLE);
138 P_MADV_BHV(UNMERGEABLE); 179 P_MADV_BHV(UNMERGEABLE);
139#ifdef MADV_HUGEPAGE
140 P_MADV_BHV(HUGEPAGE); 180 P_MADV_BHV(HUGEPAGE);
141#endif
142#ifdef MADV_NOHUGEPAGE
143 P_MADV_BHV(NOHUGEPAGE); 181 P_MADV_BHV(NOHUGEPAGE);
144#endif
145#ifdef MADV_DONTDUMP
146 P_MADV_BHV(DONTDUMP); 182 P_MADV_BHV(DONTDUMP);
147#endif
148#ifdef MADV_DODUMP
149 P_MADV_BHV(DODUMP); 183 P_MADV_BHV(DODUMP);
150#endif 184#undef P_MADV_BHV
151#undef P_MADV_PHV
152 default: break; 185 default: break;
153 } 186 }
154 187
diff --git a/tools/perf/trace/beauty/msg_flags.c b/tools/perf/trace/beauty/msg_flags.c
index 07fa8a0acad6..1106c8960cc4 100644
--- a/tools/perf/trace/beauty/msg_flags.c
+++ b/tools/perf/trace/beauty/msg_flags.c
@@ -33,7 +33,6 @@ static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size,
33 P_MSG_FLAG(OOB); 33 P_MSG_FLAG(OOB);
34 P_MSG_FLAG(PEEK); 34 P_MSG_FLAG(PEEK);
35 P_MSG_FLAG(DONTROUTE); 35 P_MSG_FLAG(DONTROUTE);
36 P_MSG_FLAG(TRYHARD);
37 P_MSG_FLAG(CTRUNC); 36 P_MSG_FLAG(CTRUNC);
38 P_MSG_FLAG(PROBE); 37 P_MSG_FLAG(PROBE);
39 P_MSG_FLAG(TRUNC); 38 P_MSG_FLAG(TRUNC);
diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c
index 0f3679e0cdcf..f55a4597fc38 100644
--- a/tools/perf/trace/beauty/open_flags.c
+++ b/tools/perf/trace/beauty/open_flags.c
@@ -1,3 +1,18 @@
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <fcntl.h>
4
5#ifndef O_DIRECT
6#define O_DIRECT 00040000
7#endif
8
9#ifndef O_DIRECTORY
10#define O_DIRECTORY 00200000
11#endif
12
13#ifndef O_NOATIME
14#define O_NOATIME 01000000
15#endif
1 16
2static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, 17static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
3 struct syscall_arg *arg) 18 struct syscall_arg *arg)
diff --git a/tools/perf/trace/beauty/sched_policy.c b/tools/perf/trace/beauty/sched_policy.c
index c205bc608b3c..34775295b9b3 100644
--- a/tools/perf/trace/beauty/sched_policy.c
+++ b/tools/perf/trace/beauty/sched_policy.c
@@ -9,6 +9,9 @@
9#ifndef SCHED_DEADLINE 9#ifndef SCHED_DEADLINE
10#define SCHED_DEADLINE 6 10#define SCHED_DEADLINE 6
11#endif 11#endif
12#ifndef SCHED_RESET_ON_FORK
13#define SCHED_RESET_ON_FORK 0x40000000
14#endif
12 15
13static size_t syscall_arg__scnprintf_sched_policy(char *bf, size_t size, 16static size_t syscall_arg__scnprintf_sched_policy(char *bf, size_t size,
14 struct syscall_arg *arg) 17 struct syscall_arg *arg)
diff --git a/tools/perf/trace/beauty/seccomp.c b/tools/perf/trace/beauty/seccomp.c
index 213c5a7e3e92..356441bce27d 100644
--- a/tools/perf/trace/beauty/seccomp.c
+++ b/tools/perf/trace/beauty/seccomp.c
@@ -1,5 +1,3 @@
1#include <linux/seccomp.h>
2
3#ifndef SECCOMP_SET_MODE_STRICT 1#ifndef SECCOMP_SET_MODE_STRICT
4#define SECCOMP_SET_MODE_STRICT 0 2#define SECCOMP_SET_MODE_STRICT 0
5#endif 3#endif
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index af68a9d488bf..3eb3edb307a4 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -1,5 +1,5 @@
1#include "../util.h" 1#include "../util.h"
2#include "../cache.h" 2#include "../config.h"
3#include "../../perf.h" 3#include "../../perf.h"
4#include "libslang.h" 4#include "libslang.h"
5#include "ui.h" 5#include "ui.h"
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 4fc208e82c6f..29dc6d20364e 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -8,6 +8,7 @@
8#include "../../util/sort.h" 8#include "../../util/sort.h"
9#include "../../util/symbol.h" 9#include "../../util/symbol.h"
10#include "../../util/evsel.h" 10#include "../../util/evsel.h"
11#include "../../util/config.h"
11#include <pthread.h> 12#include <pthread.h>
12 13
13struct disasm_line_samples { 14struct disasm_line_samples {
@@ -222,16 +223,14 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
222 } else if (ins__is_call(dl->ins)) { 223 } else if (ins__is_call(dl->ins)) {
223 ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); 224 ui_browser__write_graph(browser, SLSMG_RARROW_CHAR);
224 SLsmg_write_char(' '); 225 SLsmg_write_char(' ');
226 } else if (ins__is_ret(dl->ins)) {
227 ui_browser__write_graph(browser, SLSMG_LARROW_CHAR);
228 SLsmg_write_char(' ');
225 } else { 229 } else {
226 ui_browser__write_nstring(browser, " ", 2); 230 ui_browser__write_nstring(browser, " ", 2);
227 } 231 }
228 } else { 232 } else {
229 if (strcmp(dl->name, "retq")) { 233 ui_browser__write_nstring(browser, " ", 2);
230 ui_browser__write_nstring(browser, " ", 2);
231 } else {
232 ui_browser__write_graph(browser, SLSMG_LARROW_CHAR);
233 SLsmg_write_char(' ');
234 }
235 } 234 }
236 235
237 disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); 236 disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset);
@@ -842,14 +841,14 @@ show_help:
842 ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); 841 ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org");
843 else if (browser->selection->offset == -1) 842 else if (browser->selection->offset == -1)
844 ui_helpline__puts("Actions are only available for assembly lines."); 843 ui_helpline__puts("Actions are only available for assembly lines.");
845 else if (!browser->selection->ins) { 844 else if (!browser->selection->ins)
846 if (strcmp(browser->selection->name, "retq")) 845 goto show_sup_ins;
847 goto show_sup_ins; 846 else if (ins__is_ret(browser->selection->ins))
848 goto out; 847 goto out;
849 } else if (!(annotate_browser__jump(browser) || 848 else if (!(annotate_browser__jump(browser) ||
850 annotate_browser__callq(browser, evsel, hbt))) { 849 annotate_browser__callq(browser, evsel, hbt))) {
851show_sup_ins: 850show_sup_ins:
852 ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions."); 851 ui_helpline__puts("Actions are only available for function call/return & jump/branch instructions.");
853 } 852 }
854 continue; 853 continue;
855 case 't': 854 case 't':
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 538bae880bfe..13d414384739 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -12,35 +12,17 @@
12#include "../../util/top.h" 12#include "../../util/top.h"
13#include "../../arch/common.h" 13#include "../../arch/common.h"
14 14
15#include "../browser.h" 15#include "../browsers/hists.h"
16#include "../helpline.h" 16#include "../helpline.h"
17#include "../util.h" 17#include "../util.h"
18#include "../ui.h" 18#include "../ui.h"
19#include "map.h" 19#include "map.h"
20#include "annotate.h" 20#include "annotate.h"
21 21
22struct hist_browser {
23 struct ui_browser b;
24 struct hists *hists;
25 struct hist_entry *he_selection;
26 struct map_symbol *selection;
27 struct hist_browser_timer *hbt;
28 struct pstack *pstack;
29 struct perf_env *env;
30 int print_seq;
31 bool show_dso;
32 bool show_headers;
33 float min_pcnt;
34 u64 nr_non_filtered_entries;
35 u64 nr_hierarchy_entries;
36 u64 nr_callchain_rows;
37};
38
39extern void hist_browser__init_hpp(void); 22extern void hist_browser__init_hpp(void);
40 23
41static int hists__browser_title(struct hists *hists, 24static int perf_evsel_browser_title(struct hist_browser *browser,
42 struct hist_browser_timer *hbt, 25 char *bf, size_t size);
43 char *bf, size_t size);
44static void hist_browser__update_nr_entries(struct hist_browser *hb); 26static void hist_browser__update_nr_entries(struct hist_browser *hb);
45 27
46static struct rb_node *hists__filter_entries(struct rb_node *nd, 28static struct rb_node *hists__filter_entries(struct rb_node *nd,
@@ -585,7 +567,12 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
585 "Or reduce the sampling frequency."); 567 "Or reduce the sampling frequency.");
586} 568}
587 569
588static int hist_browser__run(struct hist_browser *browser, const char *help) 570static int hist_browser__title(struct hist_browser *browser, char *bf, size_t size)
571{
572 return browser->title ? browser->title(browser, bf, size) : 0;
573}
574
575int hist_browser__run(struct hist_browser *browser, const char *help)
589{ 576{
590 int key; 577 int key;
591 char title[160]; 578 char title[160];
@@ -595,7 +582,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *help)
595 browser->b.entries = &browser->hists->entries; 582 browser->b.entries = &browser->hists->entries;
596 browser->b.nr_entries = hist_browser__nr_entries(browser); 583 browser->b.nr_entries = hist_browser__nr_entries(browser);
597 584
598 hists__browser_title(browser->hists, hbt, title, sizeof(title)); 585 hist_browser__title(browser, title, sizeof(title));
599 586
600 if (ui_browser__show(&browser->b, title, "%s", help) < 0) 587 if (ui_browser__show(&browser->b, title, "%s", help) < 0)
601 return -1; 588 return -1;
@@ -621,8 +608,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *help)
621 ui_browser__warn_lost_events(&browser->b); 608 ui_browser__warn_lost_events(&browser->b);
622 } 609 }
623 610
624 hists__browser_title(browser->hists, 611 hist_browser__title(browser, title, sizeof(title));
625 hbt, title, sizeof(title));
626 ui_browser__show_title(&browser->b, title); 612 ui_browser__show_title(&browser->b, title);
627 continue; 613 continue;
628 } 614 }
@@ -1470,7 +1456,7 @@ static int hist_browser__show_no_entry(struct hist_browser *browser,
1470 column++ < browser->b.horiz_scroll) 1456 column++ < browser->b.horiz_scroll)
1471 continue; 1457 continue;
1472 1458
1473 ret = fmt->width(fmt, NULL, hists_to_evsel(browser->hists)); 1459 ret = fmt->width(fmt, NULL, browser->hists);
1474 1460
1475 if (first) { 1461 if (first) {
1476 /* for folded sign */ 1462 /* for folded sign */
@@ -1531,7 +1517,7 @@ static int hists_browser__scnprintf_headers(struct hist_browser *browser, char *
1531 if (perf_hpp__should_skip(fmt, hists) || column++ < browser->b.horiz_scroll) 1517 if (perf_hpp__should_skip(fmt, hists) || column++ < browser->b.horiz_scroll)
1532 continue; 1518 continue;
1533 1519
1534 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); 1520 ret = fmt->header(fmt, &dummy_hpp, hists);
1535 if (advance_hpp_check(&dummy_hpp, ret)) 1521 if (advance_hpp_check(&dummy_hpp, ret))
1536 break; 1522 break;
1537 1523
@@ -1568,7 +1554,7 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows
1568 if (column++ < browser->b.horiz_scroll) 1554 if (column++ < browser->b.horiz_scroll)
1569 continue; 1555 continue;
1570 1556
1571 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); 1557 ret = fmt->header(fmt, &dummy_hpp, hists);
1572 if (advance_hpp_check(&dummy_hpp, ret)) 1558 if (advance_hpp_check(&dummy_hpp, ret))
1573 break; 1559 break;
1574 1560
@@ -1605,7 +1591,7 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows
1605 } 1591 }
1606 first_col = false; 1592 first_col = false;
1607 1593
1608 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); 1594 ret = fmt->header(fmt, &dummy_hpp, hists);
1609 dummy_hpp.buf[ret] = '\0'; 1595 dummy_hpp.buf[ret] = '\0';
1610 1596
1611 start = trim(dummy_hpp.buf); 1597 start = trim(dummy_hpp.buf);
@@ -1622,21 +1608,38 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows
1622 return ret; 1608 return ret;
1623} 1609}
1624 1610
1625static void hist_browser__show_headers(struct hist_browser *browser) 1611static void hists_browser__hierarchy_headers(struct hist_browser *browser)
1626{ 1612{
1627 char headers[1024]; 1613 char headers[1024];
1628 1614
1629 if (symbol_conf.report_hierarchy) 1615 hists_browser__scnprintf_hierarchy_headers(browser, headers,
1630 hists_browser__scnprintf_hierarchy_headers(browser, headers, 1616 sizeof(headers));
1631 sizeof(headers)); 1617
1632 else 1618 ui_browser__gotorc(&browser->b, 0, 0);
1633 hists_browser__scnprintf_headers(browser, headers, 1619 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
1634 sizeof(headers)); 1620 ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1);
1621}
1622
1623static void hists_browser__headers(struct hist_browser *browser)
1624{
1625 char headers[1024];
1626
1627 hists_browser__scnprintf_headers(browser, headers,
1628 sizeof(headers));
1629
1635 ui_browser__gotorc(&browser->b, 0, 0); 1630 ui_browser__gotorc(&browser->b, 0, 0);
1636 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); 1631 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
1637 ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); 1632 ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1);
1638} 1633}
1639 1634
1635static void hist_browser__show_headers(struct hist_browser *browser)
1636{
1637 if (symbol_conf.report_hierarchy)
1638 hists_browser__hierarchy_headers(browser);
1639 else
1640 hists_browser__headers(browser);
1641}
1642
1640static void ui_browser__hists_init_top(struct ui_browser *browser) 1643static void ui_browser__hists_init_top(struct ui_browser *browser)
1641{ 1644{
1642 if (browser->top == NULL) { 1645 if (browser->top == NULL) {
@@ -2026,7 +2029,7 @@ static int hist_browser__dump(struct hist_browser *browser)
2026 fp = fopen(filename, "w"); 2029 fp = fopen(filename, "w");
2027 if (fp == NULL) { 2030 if (fp == NULL) {
2028 char bf[64]; 2031 char bf[64];
2029 const char *err = strerror_r(errno, bf, sizeof(bf)); 2032 const char *err = str_error_r(errno, bf, sizeof(bf));
2030 ui_helpline__fpush("Couldn't write to %s: %s", filename, err); 2033 ui_helpline__fpush("Couldn't write to %s: %s", filename, err);
2031 return -1; 2034 return -1;
2032 } 2035 }
@@ -2039,27 +2042,50 @@ static int hist_browser__dump(struct hist_browser *browser)
2039 return 0; 2042 return 0;
2040} 2043}
2041 2044
2042static struct hist_browser *hist_browser__new(struct hists *hists, 2045void hist_browser__init(struct hist_browser *browser,
2043 struct hist_browser_timer *hbt, 2046 struct hists *hists)
2044 struct perf_env *env) 2047{
2048 struct perf_hpp_fmt *fmt;
2049
2050 browser->hists = hists;
2051 browser->b.refresh = hist_browser__refresh;
2052 browser->b.refresh_dimensions = hist_browser__refresh_dimensions;
2053 browser->b.seek = ui_browser__hists_seek;
2054 browser->b.use_navkeypressed = true;
2055 browser->show_headers = symbol_conf.show_hist_headers;
2056
2057 hists__for_each_format(hists, fmt) {
2058 perf_hpp__reset_width(fmt, hists);
2059 ++browser->b.columns;
2060 }
2061}
2062
2063struct hist_browser *hist_browser__new(struct hists *hists)
2045{ 2064{
2046 struct hist_browser *browser = zalloc(sizeof(*browser)); 2065 struct hist_browser *browser = zalloc(sizeof(*browser));
2047 2066
2067 if (browser)
2068 hist_browser__init(browser, hists);
2069
2070 return browser;
2071}
2072
2073static struct hist_browser *
2074perf_evsel_browser__new(struct perf_evsel *evsel,
2075 struct hist_browser_timer *hbt,
2076 struct perf_env *env)
2077{
2078 struct hist_browser *browser = hist_browser__new(evsel__hists(evsel));
2079
2048 if (browser) { 2080 if (browser) {
2049 browser->hists = hists; 2081 browser->hbt = hbt;
2050 browser->b.refresh = hist_browser__refresh; 2082 browser->env = env;
2051 browser->b.refresh_dimensions = hist_browser__refresh_dimensions; 2083 browser->title = perf_evsel_browser_title;
2052 browser->b.seek = ui_browser__hists_seek;
2053 browser->b.use_navkeypressed = true;
2054 browser->show_headers = symbol_conf.show_hist_headers;
2055 browser->hbt = hbt;
2056 browser->env = env;
2057 } 2084 }
2058
2059 return browser; 2085 return browser;
2060} 2086}
2061 2087
2062static void hist_browser__delete(struct hist_browser *browser) 2088void hist_browser__delete(struct hist_browser *browser)
2063{ 2089{
2064 free(browser); 2090 free(browser);
2065} 2091}
@@ -2080,10 +2106,11 @@ static inline bool is_report_browser(void *timer)
2080 return timer == NULL; 2106 return timer == NULL;
2081} 2107}
2082 2108
2083static int hists__browser_title(struct hists *hists, 2109static int perf_evsel_browser_title(struct hist_browser *browser,
2084 struct hist_browser_timer *hbt,
2085 char *bf, size_t size) 2110 char *bf, size_t size)
2086{ 2111{
2112 struct hist_browser_timer *hbt = browser->hbt;
2113 struct hists *hists = browser->hists;
2087 char unit; 2114 char unit;
2088 int printed; 2115 int printed;
2089 const struct dso *dso = hists->dso_filter; 2116 const struct dso *dso = hists->dso_filter;
@@ -2640,7 +2667,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
2640 struct perf_env *env) 2667 struct perf_env *env)
2641{ 2668{
2642 struct hists *hists = evsel__hists(evsel); 2669 struct hists *hists = evsel__hists(evsel);
2643 struct hist_browser *browser = hist_browser__new(hists, hbt, env); 2670 struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env);
2644 struct branch_info *bi; 2671 struct branch_info *bi;
2645#define MAX_OPTIONS 16 2672#define MAX_OPTIONS 16
2646 char *options[MAX_OPTIONS]; 2673 char *options[MAX_OPTIONS];
@@ -2649,7 +2676,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
2649 int key = -1; 2676 int key = -1;
2650 char buf[64]; 2677 char buf[64];
2651 int delay_secs = hbt ? hbt->refresh : 0; 2678 int delay_secs = hbt ? hbt->refresh : 0;
2652 struct perf_hpp_fmt *fmt;
2653 2679
2654#define HIST_BROWSER_HELP_COMMON \ 2680#define HIST_BROWSER_HELP_COMMON \
2655 "h/?/F1 Show this window\n" \ 2681 "h/?/F1 Show this window\n" \
@@ -2708,18 +2734,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
2708 memset(options, 0, sizeof(options)); 2734 memset(options, 0, sizeof(options));
2709 memset(actions, 0, sizeof(actions)); 2735 memset(actions, 0, sizeof(actions));
2710 2736
2711 hists__for_each_format(browser->hists, fmt) {
2712 perf_hpp__reset_width(fmt, hists);
2713 /*
2714 * This is done just once, and activates the horizontal scrolling
2715 * code in the ui_browser code, it would be better to have a the
2716 * counter in the perf_hpp code, but I couldn't find doing it here
2717 * works, FIXME by setting this in hist_browser__new, for now, be
2718 * clever 8-)
2719 */
2720 ++browser->b.columns;
2721 }
2722
2723 if (symbol_conf.col_width_list_str) 2737 if (symbol_conf.col_width_list_str)
2724 perf_hpp__set_user_width(symbol_conf.col_width_list_str); 2738 perf_hpp__set_user_width(symbol_conf.col_width_list_str);
2725 2739
@@ -3185,7 +3199,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
3185 3199
3186 ui_helpline__push("Press ESC to exit"); 3200 ui_helpline__push("Press ESC to exit");
3187 3201
3188 evlist__for_each(evlist, pos) { 3202 evlist__for_each_entry(evlist, pos) {
3189 const char *ev_name = perf_evsel__name(pos); 3203 const char *ev_name = perf_evsel__name(pos);
3190 size_t line_len = strlen(ev_name) + 7; 3204 size_t line_len = strlen(ev_name) + 7;
3191 3205
@@ -3216,7 +3230,7 @@ single_entry:
3216 struct perf_evsel *pos; 3230 struct perf_evsel *pos;
3217 3231
3218 nr_entries = 0; 3232 nr_entries = 0;
3219 evlist__for_each(evlist, pos) { 3233 evlist__for_each_entry(evlist, pos) {
3220 if (perf_evsel__is_group_leader(pos)) 3234 if (perf_evsel__is_group_leader(pos))
3221 nr_entries++; 3235 nr_entries++;
3222 } 3236 }
diff --git a/tools/perf/ui/browsers/hists.h b/tools/perf/ui/browsers/hists.h
new file mode 100644
index 000000000000..39bd0f28f211
--- /dev/null
+++ b/tools/perf/ui/browsers/hists.h
@@ -0,0 +1,32 @@
1#ifndef _PERF_UI_BROWSER_HISTS_H_
2#define _PERF_UI_BROWSER_HISTS_H_ 1
3
4#include "ui/browser.h"
5
6struct hist_browser {
7 struct ui_browser b;
8 struct hists *hists;
9 struct hist_entry *he_selection;
10 struct map_symbol *selection;
11 struct hist_browser_timer *hbt;
12 struct pstack *pstack;
13 struct perf_env *env;
14 int print_seq;
15 bool show_dso;
16 bool show_headers;
17 float min_pcnt;
18 u64 nr_non_filtered_entries;
19 u64 nr_hierarchy_entries;
20 u64 nr_callchain_rows;
21
22 /* Get title string. */
23 int (*title)(struct hist_browser *browser,
24 char *bf, size_t size);
25};
26
27struct hist_browser *hist_browser__new(struct hists *hists);
28void hist_browser__delete(struct hist_browser *browser);
29int hist_browser__run(struct hist_browser *browser, const char *help);
30void hist_browser__init(struct hist_browser *browser,
31 struct hists *hists);
32#endif /* _PERF_UI_BROWSER_HISTS_H_ */
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 932adfaa05af..c5f3677f6679 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -549,7 +549,7 @@ static void perf_gtk__show_hierarchy(GtkWidget *window, struct hists *hists,
549 strcat(buf, "+"); 549 strcat(buf, "+");
550 first_col = false; 550 first_col = false;
551 551
552 fmt->header(fmt, &hpp, hists_to_evsel(hists)); 552 fmt->header(fmt, &hpp, hists);
553 strcat(buf, ltrim(rtrim(hpp.buf))); 553 strcat(buf, ltrim(rtrim(hpp.buf)));
554 } 554 }
555 } 555 }
@@ -627,7 +627,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
627 627
628 gtk_container_add(GTK_CONTAINER(window), vbox); 628 gtk_container_add(GTK_CONTAINER(window), vbox);
629 629
630 evlist__for_each(evlist, pos) { 630 evlist__for_each_entry(evlist, pos) {
631 struct hists *hists = evsel__hists(pos); 631 struct hists *hists = evsel__hists(pos);
632 const char *evname = perf_evsel__name(pos); 632 const char *evname = perf_evsel__name(pos);
633 GtkWidget *scrolled_window; 633 GtkWidget *scrolled_window;
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
index 52e7fc48af9f..00b91921edb1 100644
--- a/tools/perf/ui/gtk/util.c
+++ b/tools/perf/ui/gtk/util.c
@@ -1,4 +1,5 @@
1#include "../util.h" 1#include "../util.h"
2#include "../../util/util.h"
2#include "../../util/debug.h" 3#include "../../util/debug.h"
3#include "gtk.h" 4#include "gtk.h"
4 5
diff --git a/tools/perf/ui/helpline.c b/tools/perf/ui/helpline.c
index 700fb3cfa1c7..5b74a7eba210 100644
--- a/tools/perf/ui/helpline.c
+++ b/tools/perf/ui/helpline.c
@@ -5,6 +5,7 @@
5#include "../debug.h" 5#include "../debug.h"
6#include "helpline.h" 6#include "helpline.h"
7#include "ui.h" 7#include "ui.h"
8#include "../util.h"
8 9
9char ui_helpline__current[512]; 10char ui_helpline__current[512];
10 11
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index af07ffb129ca..4274969ddc89 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -215,9 +215,10 @@ static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b,
215 215
216static int hpp__width_fn(struct perf_hpp_fmt *fmt, 216static int hpp__width_fn(struct perf_hpp_fmt *fmt,
217 struct perf_hpp *hpp __maybe_unused, 217 struct perf_hpp *hpp __maybe_unused,
218 struct perf_evsel *evsel) 218 struct hists *hists)
219{ 219{
220 int len = fmt->user_len ?: fmt->len; 220 int len = fmt->user_len ?: fmt->len;
221 struct perf_evsel *evsel = hists_to_evsel(hists);
221 222
222 if (symbol_conf.event_group) 223 if (symbol_conf.event_group)
223 len = max(len, evsel->nr_members * fmt->len); 224 len = max(len, evsel->nr_members * fmt->len);
@@ -229,9 +230,9 @@ static int hpp__width_fn(struct perf_hpp_fmt *fmt,
229} 230}
230 231
231static int hpp__header_fn(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 232static int hpp__header_fn(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
232 struct perf_evsel *evsel) 233 struct hists *hists)
233{ 234{
234 int len = hpp__width_fn(fmt, hpp, evsel); 235 int len = hpp__width_fn(fmt, hpp, hists);
235 return scnprintf(hpp->buf, hpp->size, "%*s", len, fmt->name); 236 return scnprintf(hpp->buf, hpp->size, "%*s", len, fmt->name);
236} 237}
237 238
@@ -632,7 +633,7 @@ unsigned int hists__sort_list_width(struct hists *hists)
632 else 633 else
633 ret += 2; 634 ret += 2;
634 635
635 ret += fmt->width(fmt, &dummy_hpp, hists_to_evsel(hists)); 636 ret += fmt->width(fmt, &dummy_hpp, hists);
636 } 637 }
637 638
638 if (verbose && hists__has(hists, sym)) /* Addr + origin */ 639 if (verbose && hists__has(hists, sym)) /* Addr + origin */
@@ -657,7 +658,7 @@ unsigned int hists__overhead_width(struct hists *hists)
657 else 658 else
658 ret += 2; 659 ret += 2;
659 660
660 ret += fmt->width(fmt, &dummy_hpp, hists_to_evsel(hists)); 661 ret += fmt->width(fmt, &dummy_hpp, hists);
661 } 662 }
662 663
663 return ret; 664 return ret;
@@ -765,7 +766,7 @@ int perf_hpp__setup_hists_formats(struct perf_hpp_list *list,
765 if (!symbol_conf.report_hierarchy) 766 if (!symbol_conf.report_hierarchy)
766 return 0; 767 return 0;
767 768
768 evlist__for_each(evlist, evsel) { 769 evlist__for_each_entry(evlist, evsel) {
769 hists = evsel__hists(evsel); 770 hists = evsel__hists(evsel);
770 771
771 perf_hpp_list__for_each_sort_list(list, fmt) { 772 perf_hpp_list__for_each_sort_list(list, fmt) {
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index ba51fa8a1176..1f6b0994f4f4 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -60,6 +60,13 @@ static inline int setup_gtk_browser(void) { return -1; }
60static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {} 60static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {}
61#endif 61#endif
62 62
63int stdio__config_color(const struct option *opt __maybe_unused,
64 const char *mode, int unset __maybe_unused)
65{
66 perf_use_color_default = perf_config_colorbool("color.ui", mode, -1);
67 return 0;
68}
69
63void setup_browser(bool fallback_to_pager) 70void setup_browser(bool fallback_to_pager)
64{ 71{
65 if (use_browser < 2 && (!isatty(1) || dump_trace)) 72 if (use_browser < 2 && (!isatty(1) || dump_trace))
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 560eb47d56f9..f04a63112079 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -492,14 +492,15 @@ out:
492} 492}
493 493
494static int hist_entry__fprintf(struct hist_entry *he, size_t size, 494static int hist_entry__fprintf(struct hist_entry *he, size_t size,
495 struct hists *hists, 495 char *bf, size_t bfsz, FILE *fp,
496 char *bf, size_t bfsz, FILE *fp) 496 bool use_callchain)
497{ 497{
498 int ret; 498 int ret;
499 struct perf_hpp hpp = { 499 struct perf_hpp hpp = {
500 .buf = bf, 500 .buf = bf,
501 .size = size, 501 .size = size,
502 }; 502 };
503 struct hists *hists = he->hists;
503 u64 total_period = hists->stats.total_period; 504 u64 total_period = hists->stats.total_period;
504 505
505 if (size == 0 || size > bfsz) 506 if (size == 0 || size > bfsz)
@@ -512,7 +513,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
512 513
513 ret = fprintf(fp, "%s\n", bf); 514 ret = fprintf(fp, "%s\n", bf);
514 515
515 if (symbol_conf.use_callchain) 516 if (use_callchain)
516 ret += hist_entry_callchain__fprintf(he, total_period, 0, fp); 517 ret += hist_entry_callchain__fprintf(he, total_period, 0, fp);
517 518
518 return ret; 519 return ret;
@@ -548,7 +549,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
548 struct perf_hpp_list_node, list); 549 struct perf_hpp_list_node, list);
549 550
550 perf_hpp_list__for_each_format(&fmt_node->hpp, fmt) { 551 perf_hpp_list__for_each_format(&fmt_node->hpp, fmt) {
551 fmt->header(fmt, hpp, hists_to_evsel(hists)); 552 fmt->header(fmt, hpp, hists);
552 fprintf(fp, "%s%s", hpp->buf, sep ?: " "); 553 fprintf(fp, "%s%s", hpp->buf, sep ?: " ");
553 } 554 }
554 555
@@ -568,7 +569,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
568 header_width += fprintf(fp, "+"); 569 header_width += fprintf(fp, "+");
569 first_col = false; 570 first_col = false;
570 571
571 fmt->header(fmt, hpp, hists_to_evsel(hists)); 572 fmt->header(fmt, hpp, hists);
572 573
573 header_width += fprintf(fp, "%s", trim(hpp->buf)); 574 header_width += fprintf(fp, "%s", trim(hpp->buf));
574 } 575 }
@@ -589,7 +590,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
589 fprintf(fp, "%s", sep ?: ".."); 590 fprintf(fp, "%s", sep ?: "..");
590 first_col = false; 591 first_col = false;
591 592
592 width = fmt->width(fmt, hpp, hists_to_evsel(hists)); 593 width = fmt->width(fmt, hpp, hists);
593 fprintf(fp, "%.*s", width, dots); 594 fprintf(fp, "%.*s", width, dots);
594 } 595 }
595 596
@@ -606,7 +607,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
606 width++; /* for '+' sign between column header */ 607 width++; /* for '+' sign between column header */
607 first_col = false; 608 first_col = false;
608 609
609 width += fmt->width(fmt, hpp, hists_to_evsel(hists)); 610 width += fmt->width(fmt, hpp, hists);
610 } 611 }
611 612
612 if (width > header_width) 613 if (width > header_width)
@@ -622,47 +623,31 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
622 return 2; 623 return 2;
623} 624}
624 625
625size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 626static int
626 int max_cols, float min_pcnt, FILE *fp) 627hists__fprintf_hierarchy_headers(struct hists *hists,
628 struct perf_hpp *hpp,
629 FILE *fp)
627{ 630{
628 struct perf_hpp_fmt *fmt;
629 struct perf_hpp_list_node *fmt_node; 631 struct perf_hpp_list_node *fmt_node;
630 struct rb_node *nd; 632 struct perf_hpp_fmt *fmt;
631 size_t ret = 0;
632 unsigned int width;
633 const char *sep = symbol_conf.field_sep;
634 int nr_rows = 0;
635 char bf[96];
636 struct perf_hpp dummy_hpp = {
637 .buf = bf,
638 .size = sizeof(bf),
639 };
640 bool first = true;
641 size_t linesz;
642 char *line = NULL;
643 unsigned indent;
644
645 init_rem_hits();
646
647 hists__for_each_format(hists, fmt)
648 perf_hpp__reset_width(fmt, hists);
649
650 if (symbol_conf.col_width_list_str)
651 perf_hpp__set_user_width(symbol_conf.col_width_list_str);
652 633
653 if (!show_header) 634 list_for_each_entry(fmt_node, &hists->hpp_formats, list) {
654 goto print_entries; 635 perf_hpp_list__for_each_format(&fmt_node->hpp, fmt)
636 perf_hpp__reset_width(fmt, hists);
637 }
655 638
656 fprintf(fp, "# "); 639 return print_hierarchy_header(hists, hpp, symbol_conf.field_sep, fp);
640}
657 641
658 if (symbol_conf.report_hierarchy) { 642static int
659 list_for_each_entry(fmt_node, &hists->hpp_formats, list) { 643hists__fprintf_standard_headers(struct hists *hists,
660 perf_hpp_list__for_each_format(&fmt_node->hpp, fmt) 644 struct perf_hpp *hpp,
661 perf_hpp__reset_width(fmt, hists); 645 FILE *fp)
662 } 646{
663 nr_rows += print_hierarchy_header(hists, &dummy_hpp, sep, fp); 647 struct perf_hpp_fmt *fmt;
664 goto print_entries; 648 unsigned int width;
665 } 649 const char *sep = symbol_conf.field_sep;
650 bool first = true;
666 651
667 hists__for_each_format(hists, fmt) { 652 hists__for_each_format(hists, fmt) {
668 if (perf_hpp__should_skip(fmt, hists)) 653 if (perf_hpp__should_skip(fmt, hists))
@@ -673,16 +658,14 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
673 else 658 else
674 first = false; 659 first = false;
675 660
676 fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); 661 fmt->header(fmt, hpp, hists);
677 fprintf(fp, "%s", bf); 662 fprintf(fp, "%s", hpp->buf);
678 } 663 }
679 664
680 fprintf(fp, "\n"); 665 fprintf(fp, "\n");
681 if (max_rows && ++nr_rows >= max_rows)
682 goto out;
683 666
684 if (sep) 667 if (sep)
685 goto print_entries; 668 return 1;
686 669
687 first = true; 670 first = true;
688 671
@@ -699,20 +682,60 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
699 else 682 else
700 first = false; 683 first = false;
701 684
702 width = fmt->width(fmt, &dummy_hpp, hists_to_evsel(hists)); 685 width = fmt->width(fmt, hpp, hists);
703 for (i = 0; i < width; i++) 686 for (i = 0; i < width; i++)
704 fprintf(fp, "."); 687 fprintf(fp, ".");
705 } 688 }
706 689
707 fprintf(fp, "\n"); 690 fprintf(fp, "\n");
708 if (max_rows && ++nr_rows >= max_rows)
709 goto out;
710
711 fprintf(fp, "#\n"); 691 fprintf(fp, "#\n");
712 if (max_rows && ++nr_rows >= max_rows) 692 return 3;
693}
694
695static int hists__fprintf_headers(struct hists *hists, FILE *fp)
696{
697 char bf[96];
698 struct perf_hpp dummy_hpp = {
699 .buf = bf,
700 .size = sizeof(bf),
701 };
702
703 fprintf(fp, "# ");
704
705 if (symbol_conf.report_hierarchy)
706 return hists__fprintf_hierarchy_headers(hists, &dummy_hpp, fp);
707 else
708 return hists__fprintf_standard_headers(hists, &dummy_hpp, fp);
709
710}
711
712size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
713 int max_cols, float min_pcnt, FILE *fp,
714 bool use_callchain)
715{
716 struct perf_hpp_fmt *fmt;
717 struct rb_node *nd;
718 size_t ret = 0;
719 const char *sep = symbol_conf.field_sep;
720 int nr_rows = 0;
721 size_t linesz;
722 char *line = NULL;
723 unsigned indent;
724
725 init_rem_hits();
726
727 hists__for_each_format(hists, fmt)
728 perf_hpp__reset_width(fmt, hists);
729
730 if (symbol_conf.col_width_list_str)
731 perf_hpp__set_user_width(symbol_conf.col_width_list_str);
732
733 if (show_header)
734 nr_rows += hists__fprintf_headers(hists, fp);
735
736 if (max_rows && nr_rows >= max_rows)
713 goto out; 737 goto out;
714 738
715print_entries:
716 linesz = hists__sort_list_width(hists) + 3 + 1; 739 linesz = hists__sort_list_width(hists) + 3 + 1;
717 linesz += perf_hpp__color_overhead(); 740 linesz += perf_hpp__color_overhead();
718 line = malloc(linesz); 741 line = malloc(linesz);
@@ -734,7 +757,7 @@ print_entries:
734 if (percent < min_pcnt) 757 if (percent < min_pcnt)
735 continue; 758 continue;
736 759
737 ret += hist_entry__fprintf(h, max_cols, hists, line, linesz, fp); 760 ret += hist_entry__fprintf(h, max_cols, line, linesz, fp, use_callchain);
738 761
739 if (max_rows && ++nr_rows >= max_rows) 762 if (max_rows && ++nr_rows >= max_rows)
740 break; 763 break;
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index 7dfeba0a91f3..4ea2ba861fc2 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -1,3 +1,4 @@
1#include <errno.h>
1#include <signal.h> 2#include <signal.h>
2#include <stdbool.h> 3#include <stdbool.h>
3#ifdef HAVE_BACKTRACE_SUPPORT 4#ifdef HAVE_BACKTRACE_SUPPORT
@@ -6,6 +7,7 @@
6 7
7#include "../../util/cache.h" 8#include "../../util/cache.h"
8#include "../../util/debug.h" 9#include "../../util/debug.h"
10#include "../../util/util.h"
9#include "../browser.h" 11#include "../browser.h"
10#include "../helpline.h" 12#include "../helpline.h"
11#include "../ui.h" 13#include "../ui.h"
diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h
index ab88383f8be8..4b6fb6c7a542 100644
--- a/tools/perf/ui/ui.h
+++ b/tools/perf/ui/ui.h
@@ -26,4 +26,8 @@ static inline void ui__exit(bool wait_for_ok __maybe_unused) {}
26 26
27void ui__refresh_dimensions(bool force); 27void ui__refresh_dimensions(bool force);
28 28
29struct option;
30
31int stdio__config_color(const struct option *opt, const char *mode, int unset);
32
29#endif /* _PERF_UI_H_ */ 33#endif /* _PERF_UI_H_ */
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 8c6c8a0ca642..91c5f6e1af59 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -84,6 +84,7 @@ libperf-y += parse-regs-options.o
84libperf-y += term.o 84libperf-y += term.o
85libperf-y += help-unknown-cmd.o 85libperf-y += help-unknown-cmd.o
86libperf-y += mem-events.o 86libperf-y += mem-events.o
87libperf-y += vsprintf.o
87 88
88libperf-$(CONFIG_LIBBPF) += bpf-loader.o 89libperf-$(CONFIG_LIBBPF) += bpf-loader.o
89libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o 90libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
@@ -99,7 +100,10 @@ libperf-$(CONFIG_DWARF) += probe-finder.o
99libperf-$(CONFIG_DWARF) += dwarf-aux.o 100libperf-$(CONFIG_DWARF) += dwarf-aux.o
100 101
101libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o 102libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
103libperf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind-local.o
102libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o 104libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o
105libperf-$(CONFIG_LIBUNWIND_X86) += libunwind/x86_32.o
106libperf-$(CONFIG_LIBUNWIND_AARCH64) += libunwind/arm64.o
103 107
104libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o 108libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
105 109
@@ -108,6 +112,7 @@ libperf-y += scripting-engines/
108libperf-$(CONFIG_ZLIB) += zlib.o 112libperf-$(CONFIG_ZLIB) += zlib.o
109libperf-$(CONFIG_LZMA) += lzma.o 113libperf-$(CONFIG_LZMA) += lzma.o
110libperf-y += demangle-java.o 114libperf-y += demangle-java.o
115libperf-y += demangle-rust.o
111 116
112ifdef CONFIG_JITDUMP 117ifdef CONFIG_JITDUMP
113libperf-$(CONFIG_LIBELF) += jitdump.o 118libperf-$(CONFIG_LIBELF) += jitdump.o
@@ -173,3 +178,7 @@ $(OUTPUT)util/libstring.o: ../lib/string.c FORCE
173$(OUTPUT)util/hweight.o: ../lib/hweight.c FORCE 178$(OUTPUT)util/hweight.o: ../lib/hweight.c FORCE
174 $(call rule_mkdir) 179 $(call rule_mkdir)
175 $(call if_changed_dep,cc_o_c) 180 $(call if_changed_dep,cc_o_c)
181
182$(OUTPUT)util/vsprintf.o: ../lib/vsprintf.c FORCE
183 $(call rule_mkdir)
184 $(call if_changed_dep,cc_o_c)
diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c
index c0b43ee40d95..6455471d9cd1 100644
--- a/tools/perf/util/alias.c
+++ b/tools/perf/util/alias.c
@@ -1,4 +1,6 @@
1#include "cache.h" 1#include "cache.h"
2#include "util.h"
3#include "config.h"
2 4
3static const char *alias_key; 5static const char *alias_key;
4static char *alias_val; 6static char *alias_val;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 7e5a1e8874ce..e9825fe825fd 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -354,6 +354,15 @@ static struct ins_ops nop_ops = {
354 .scnprintf = nop__scnprintf, 354 .scnprintf = nop__scnprintf,
355}; 355};
356 356
357static struct ins_ops ret_ops = {
358 .scnprintf = ins__raw_scnprintf,
359};
360
361bool ins__is_ret(const struct ins *ins)
362{
363 return ins->ops == &ret_ops;
364}
365
357static struct ins instructions[] = { 366static struct ins instructions[] = {
358 { .name = "add", .ops = &mov_ops, }, 367 { .name = "add", .ops = &mov_ops, },
359 { .name = "addl", .ops = &mov_ops, }, 368 { .name = "addl", .ops = &mov_ops, },
@@ -444,6 +453,7 @@ static struct ins instructions[] = {
444 { .name = "xadd", .ops = &mov_ops, }, 453 { .name = "xadd", .ops = &mov_ops, },
445 { .name = "xbeginl", .ops = &jump_ops, }, 454 { .name = "xbeginl", .ops = &jump_ops, },
446 { .name = "xbeginq", .ops = &jump_ops, }, 455 { .name = "xbeginq", .ops = &jump_ops, },
456 { .name = "retq", .ops = &ret_ops, },
447}; 457};
448 458
449static int ins__key_cmp(const void *name, const void *insp) 459static int ins__key_cmp(const void *name, const void *insp)
@@ -1512,13 +1522,14 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
1512 const char *d_filename; 1522 const char *d_filename;
1513 const char *evsel_name = perf_evsel__name(evsel); 1523 const char *evsel_name = perf_evsel__name(evsel);
1514 struct annotation *notes = symbol__annotation(sym); 1524 struct annotation *notes = symbol__annotation(sym);
1525 struct sym_hist *h = annotation__histogram(notes, evsel->idx);
1515 struct disasm_line *pos, *queue = NULL; 1526 struct disasm_line *pos, *queue = NULL;
1516 u64 start = map__rip_2objdump(map, sym->start); 1527 u64 start = map__rip_2objdump(map, sym->start);
1517 int printed = 2, queue_len = 0; 1528 int printed = 2, queue_len = 0;
1518 int more = 0; 1529 int more = 0;
1519 u64 len; 1530 u64 len;
1520 int width = 8; 1531 int width = 8;
1521 int namelen, evsel_name_len, graph_dotted_len; 1532 int graph_dotted_len;
1522 1533
1523 filename = strdup(dso->long_name); 1534 filename = strdup(dso->long_name);
1524 if (!filename) 1535 if (!filename)
@@ -1530,17 +1541,14 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
1530 d_filename = basename(filename); 1541 d_filename = basename(filename);
1531 1542
1532 len = symbol__size(sym); 1543 len = symbol__size(sym);
1533 namelen = strlen(d_filename);
1534 evsel_name_len = strlen(evsel_name);
1535 1544
1536 if (perf_evsel__is_group_event(evsel)) 1545 if (perf_evsel__is_group_event(evsel))
1537 width *= evsel->nr_members; 1546 width *= evsel->nr_members;
1538 1547
1539 printf(" %-*.*s| Source code & Disassembly of %s for %s\n", 1548 graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n",
1540 width, width, "Percent", d_filename, evsel_name); 1549 width, width, "Percent", d_filename, evsel_name, h->sum);
1541 1550
1542 graph_dotted_len = width + namelen + evsel_name_len; 1551 printf("%-*.*s----\n",
1543 printf("-%-*.*s-----------------------------------------\n",
1544 graph_dotted_len, graph_dotted_len, graph_dotted_line); 1552 graph_dotted_len, graph_dotted_len, graph_dotted_line);
1545 1553
1546 if (verbose) 1554 if (verbose)
@@ -1676,11 +1684,6 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
1676 return 0; 1684 return 0;
1677} 1685}
1678 1686
1679int hist_entry__annotate(struct hist_entry *he, size_t privsize)
1680{
1681 return symbol__annotate(he->ms.sym, he->ms.map, privsize);
1682}
1683
1684bool ui__has_annotation(void) 1687bool ui__has_annotation(void)
1685{ 1688{
1686 return use_browser == 1 && perf_hpp_list.sym; 1689 return use_browser == 1 && perf_hpp_list.sym;
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 9241f8c2b7e1..a23084f54128 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -48,6 +48,7 @@ struct ins {
48 48
49bool ins__is_jump(const struct ins *ins); 49bool ins__is_jump(const struct ins *ins);
50bool ins__is_call(const struct ins *ins); 50bool ins__is_call(const struct ins *ins);
51bool ins__is_ret(const struct ins *ins);
51int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); 52int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops);
52 53
53struct annotation; 54struct annotation;
@@ -156,8 +157,6 @@ void symbol__annotate_zero_histograms(struct symbol *sym);
156 157
157int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); 158int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize);
158 159
159int hist_entry__annotate(struct hist_entry *he, size_t privsize);
160
161int symbol__annotate_init(struct map *map, struct symbol *sym); 160int symbol__annotate_init(struct map *map, struct symbol *sym);
162int symbol__annotate_printf(struct symbol *sym, struct map *map, 161int symbol__annotate_printf(struct symbol *sym, struct map *map,
163 struct perf_evsel *evsel, bool full_paths, 162 struct perf_evsel *evsel, bool full_paths,
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 767989e0e312..ac5f0d7167e6 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -63,6 +63,7 @@ enum itrace_period_type {
63 * @calls: limit branch samples to calls (can be combined with @returns) 63 * @calls: limit branch samples to calls (can be combined with @returns)
64 * @returns: limit branch samples to returns (can be combined with @calls) 64 * @returns: limit branch samples to returns (can be combined with @calls)
65 * @callchain: add callchain to 'instructions' events 65 * @callchain: add callchain to 'instructions' events
66 * @thread_stack: feed branches to the thread_stack
66 * @last_branch: add branch context to 'instruction' events 67 * @last_branch: add branch context to 'instruction' events
67 * @callchain_sz: maximum callchain size 68 * @callchain_sz: maximum callchain size
68 * @last_branch_sz: branch context size 69 * @last_branch_sz: branch context size
@@ -82,6 +83,7 @@ struct itrace_synth_opts {
82 bool calls; 83 bool calls;
83 bool returns; 84 bool returns;
84 bool callchain; 85 bool callchain;
86 bool thread_stack;
85 bool last_branch; 87 bool last_branch;
86 unsigned int callchain_sz; 88 unsigned int callchain_sz;
87 unsigned int last_branch_sz; 89 unsigned int last_branch_sz;
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 493307d1414c..1f12e4e40006 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -37,6 +37,9 @@ DEFINE_PRINT_FN(info, 1)
37DEFINE_PRINT_FN(debug, 1) 37DEFINE_PRINT_FN(debug, 1)
38 38
39struct bpf_prog_priv { 39struct bpf_prog_priv {
40 bool is_tp;
41 char *sys_name;
42 char *evt_name;
40 struct perf_probe_event pev; 43 struct perf_probe_event pev;
41 bool need_prologue; 44 bool need_prologue;
42 struct bpf_insn *insns_buf; 45 struct bpf_insn *insns_buf;
@@ -118,6 +121,8 @@ clear_prog_priv(struct bpf_program *prog __maybe_unused,
118 cleanup_perf_probe_events(&priv->pev, 1); 121 cleanup_perf_probe_events(&priv->pev, 1);
119 zfree(&priv->insns_buf); 122 zfree(&priv->insns_buf);
120 zfree(&priv->type_mapping); 123 zfree(&priv->type_mapping);
124 zfree(&priv->sys_name);
125 zfree(&priv->evt_name);
121 free(priv); 126 free(priv);
122} 127}
123 128
@@ -269,7 +274,8 @@ nextline:
269} 274}
270 275
271static int 276static int
272parse_prog_config(const char *config_str, struct perf_probe_event *pev) 277parse_prog_config(const char *config_str, const char **p_main_str,
278 bool *is_tp, struct perf_probe_event *pev)
273{ 279{
274 int err; 280 int err;
275 const char *main_str = parse_prog_config_kvpair(config_str, pev); 281 const char *main_str = parse_prog_config_kvpair(config_str, pev);
@@ -277,6 +283,22 @@ parse_prog_config(const char *config_str, struct perf_probe_event *pev)
277 if (IS_ERR(main_str)) 283 if (IS_ERR(main_str))
278 return PTR_ERR(main_str); 284 return PTR_ERR(main_str);
279 285
286 *p_main_str = main_str;
287 if (!strchr(main_str, '=')) {
288 /* Is a tracepoint event? */
289 const char *s = strchr(main_str, ':');
290
291 if (!s) {
292 pr_debug("bpf: '%s' is not a valid tracepoint\n",
293 config_str);
294 return -BPF_LOADER_ERRNO__CONFIG;
295 }
296
297 *is_tp = true;
298 return 0;
299 }
300
301 *is_tp = false;
280 err = parse_perf_probe_command(main_str, pev); 302 err = parse_perf_probe_command(main_str, pev);
281 if (err < 0) { 303 if (err < 0) {
282 pr_debug("bpf: '%s' is not a valid config string\n", 304 pr_debug("bpf: '%s' is not a valid config string\n",
@@ -292,7 +314,8 @@ config_bpf_program(struct bpf_program *prog)
292{ 314{
293 struct perf_probe_event *pev = NULL; 315 struct perf_probe_event *pev = NULL;
294 struct bpf_prog_priv *priv = NULL; 316 struct bpf_prog_priv *priv = NULL;
295 const char *config_str; 317 const char *config_str, *main_str;
318 bool is_tp = false;
296 int err; 319 int err;
297 320
298 /* Initialize per-program probing setting */ 321 /* Initialize per-program probing setting */
@@ -313,10 +336,19 @@ config_bpf_program(struct bpf_program *prog)
313 pev = &priv->pev; 336 pev = &priv->pev;
314 337
315 pr_debug("bpf: config program '%s'\n", config_str); 338 pr_debug("bpf: config program '%s'\n", config_str);
316 err = parse_prog_config(config_str, pev); 339 err = parse_prog_config(config_str, &main_str, &is_tp, pev);
317 if (err) 340 if (err)
318 goto errout; 341 goto errout;
319 342
343 if (is_tp) {
344 char *s = strchr(main_str, ':');
345
346 priv->is_tp = true;
347 priv->sys_name = strndup(main_str, s - main_str);
348 priv->evt_name = strdup(s + 1);
349 goto set_priv;
350 }
351
320 if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) { 352 if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
321 pr_debug("bpf: '%s': group for event is set and not '%s'.\n", 353 pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
322 config_str, PERF_BPF_PROBE_GROUP); 354 config_str, PERF_BPF_PROBE_GROUP);
@@ -339,7 +371,8 @@ config_bpf_program(struct bpf_program *prog)
339 } 371 }
340 pr_debug("bpf: config '%s' is ok\n", config_str); 372 pr_debug("bpf: config '%s' is ok\n", config_str);
341 373
342 err = bpf_program__set_private(prog, priv, clear_prog_priv); 374set_priv:
375 err = bpf_program__set_priv(prog, priv, clear_prog_priv);
343 if (err) { 376 if (err) {
344 pr_debug("Failed to set priv for program '%s'\n", config_str); 377 pr_debug("Failed to set priv for program '%s'\n", config_str);
345 goto errout; 378 goto errout;
@@ -380,15 +413,14 @@ preproc_gen_prologue(struct bpf_program *prog, int n,
380 struct bpf_insn *orig_insns, int orig_insns_cnt, 413 struct bpf_insn *orig_insns, int orig_insns_cnt,
381 struct bpf_prog_prep_result *res) 414 struct bpf_prog_prep_result *res)
382{ 415{
416 struct bpf_prog_priv *priv = bpf_program__priv(prog);
383 struct probe_trace_event *tev; 417 struct probe_trace_event *tev;
384 struct perf_probe_event *pev; 418 struct perf_probe_event *pev;
385 struct bpf_prog_priv *priv;
386 struct bpf_insn *buf; 419 struct bpf_insn *buf;
387 size_t prologue_cnt = 0; 420 size_t prologue_cnt = 0;
388 int i, err; 421 int i, err;
389 422
390 err = bpf_program__get_private(prog, (void **)&priv); 423 if (IS_ERR(priv) || !priv || priv->is_tp)
391 if (err || !priv)
392 goto errout; 424 goto errout;
393 425
394 pev = &priv->pev; 426 pev = &priv->pev;
@@ -535,17 +567,21 @@ static int map_prologue(struct perf_probe_event *pev, int *mapping,
535 567
536static int hook_load_preprocessor(struct bpf_program *prog) 568static int hook_load_preprocessor(struct bpf_program *prog)
537{ 569{
570 struct bpf_prog_priv *priv = bpf_program__priv(prog);
538 struct perf_probe_event *pev; 571 struct perf_probe_event *pev;
539 struct bpf_prog_priv *priv;
540 bool need_prologue = false; 572 bool need_prologue = false;
541 int err, i; 573 int err, i;
542 574
543 err = bpf_program__get_private(prog, (void **)&priv); 575 if (IS_ERR(priv) || !priv) {
544 if (err || !priv) {
545 pr_debug("Internal error when hook preprocessor\n"); 576 pr_debug("Internal error when hook preprocessor\n");
546 return -BPF_LOADER_ERRNO__INTERNAL; 577 return -BPF_LOADER_ERRNO__INTERNAL;
547 } 578 }
548 579
580 if (priv->is_tp) {
581 priv->need_prologue = false;
582 return 0;
583 }
584
549 pev = &priv->pev; 585 pev = &priv->pev;
550 for (i = 0; i < pev->ntevs; i++) { 586 for (i = 0; i < pev->ntevs; i++) {
551 struct probe_trace_event *tev = &pev->tevs[i]; 587 struct probe_trace_event *tev = &pev->tevs[i];
@@ -607,9 +643,18 @@ int bpf__probe(struct bpf_object *obj)
607 if (err) 643 if (err)
608 goto out; 644 goto out;
609 645
610 err = bpf_program__get_private(prog, (void **)&priv); 646 priv = bpf_program__priv(prog);
611 if (err || !priv) 647 if (IS_ERR(priv) || !priv) {
648 err = PTR_ERR(priv);
612 goto out; 649 goto out;
650 }
651
652 if (priv->is_tp) {
653 bpf_program__set_tracepoint(prog);
654 continue;
655 }
656
657 bpf_program__set_kprobe(prog);
613 pev = &priv->pev; 658 pev = &priv->pev;
614 659
615 err = convert_perf_probe_events(pev, 1); 660 err = convert_perf_probe_events(pev, 1);
@@ -645,13 +690,12 @@ int bpf__unprobe(struct bpf_object *obj)
645{ 690{
646 int err, ret = 0; 691 int err, ret = 0;
647 struct bpf_program *prog; 692 struct bpf_program *prog;
648 struct bpf_prog_priv *priv;
649 693
650 bpf_object__for_each_program(prog, obj) { 694 bpf_object__for_each_program(prog, obj) {
695 struct bpf_prog_priv *priv = bpf_program__priv(prog);
651 int i; 696 int i;
652 697
653 err = bpf_program__get_private(prog, (void **)&priv); 698 if (IS_ERR(priv) || !priv || priv->is_tp)
654 if (err || !priv)
655 continue; 699 continue;
656 700
657 for (i = 0; i < priv->pev.ntevs; i++) { 701 for (i = 0; i < priv->pev.ntevs; i++) {
@@ -694,26 +738,34 @@ int bpf__load(struct bpf_object *obj)
694 return 0; 738 return 0;
695} 739}
696 740
697int bpf__foreach_tev(struct bpf_object *obj, 741int bpf__foreach_event(struct bpf_object *obj,
698 bpf_prog_iter_callback_t func, 742 bpf_prog_iter_callback_t func,
699 void *arg) 743 void *arg)
700{ 744{
701 struct bpf_program *prog; 745 struct bpf_program *prog;
702 int err; 746 int err;
703 747
704 bpf_object__for_each_program(prog, obj) { 748 bpf_object__for_each_program(prog, obj) {
749 struct bpf_prog_priv *priv = bpf_program__priv(prog);
705 struct probe_trace_event *tev; 750 struct probe_trace_event *tev;
706 struct perf_probe_event *pev; 751 struct perf_probe_event *pev;
707 struct bpf_prog_priv *priv;
708 int i, fd; 752 int i, fd;
709 753
710 err = bpf_program__get_private(prog, 754 if (IS_ERR(priv) || !priv) {
711 (void **)&priv);
712 if (err || !priv) {
713 pr_debug("bpf: failed to get private field\n"); 755 pr_debug("bpf: failed to get private field\n");
714 return -BPF_LOADER_ERRNO__INTERNAL; 756 return -BPF_LOADER_ERRNO__INTERNAL;
715 } 757 }
716 758
759 if (priv->is_tp) {
760 fd = bpf_program__fd(prog);
761 err = (*func)(priv->sys_name, priv->evt_name, fd, arg);
762 if (err) {
763 pr_debug("bpf: tracepoint call back failed, stop iterate\n");
764 return err;
765 }
766 continue;
767 }
768
717 pev = &priv->pev; 769 pev = &priv->pev;
718 for (i = 0; i < pev->ntevs; i++) { 770 for (i = 0; i < pev->ntevs; i++) {
719 tev = &pev->tevs[i]; 771 tev = &pev->tevs[i];
@@ -731,7 +783,7 @@ int bpf__foreach_tev(struct bpf_object *obj,
731 return fd; 783 return fd;
732 } 784 }
733 785
734 err = (*func)(tev, fd, arg); 786 err = (*func)(tev->group, tev->event, fd, arg);
735 if (err) { 787 if (err) {
736 pr_debug("bpf: call back failed, stop iterate\n"); 788 pr_debug("bpf: call back failed, stop iterate\n");
737 return err; 789 return err;
@@ -897,15 +949,12 @@ bpf_map_priv__clone(struct bpf_map_priv *priv)
897static int 949static int
898bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op) 950bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
899{ 951{
900 struct bpf_map_priv *priv; 952 const char *map_name = bpf_map__name(map);
901 const char *map_name; 953 struct bpf_map_priv *priv = bpf_map__priv(map);
902 int err;
903 954
904 map_name = bpf_map__get_name(map); 955 if (IS_ERR(priv)) {
905 err = bpf_map__get_private(map, (void **)&priv);
906 if (err) {
907 pr_debug("Failed to get private from map %s\n", map_name); 956 pr_debug("Failed to get private from map %s\n", map_name);
908 return err; 957 return PTR_ERR(priv);
909 } 958 }
910 959
911 if (!priv) { 960 if (!priv) {
@@ -916,7 +965,7 @@ bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
916 } 965 }
917 INIT_LIST_HEAD(&priv->ops_list); 966 INIT_LIST_HEAD(&priv->ops_list);
918 967
919 if (bpf_map__set_private(map, priv, bpf_map_priv__clear)) { 968 if (bpf_map__set_priv(map, priv, bpf_map_priv__clear)) {
920 free(priv); 969 free(priv);
921 return -BPF_LOADER_ERRNO__INTERNAL; 970 return -BPF_LOADER_ERRNO__INTERNAL;
922 } 971 }
@@ -948,30 +997,26 @@ static int
948__bpf_map__config_value(struct bpf_map *map, 997__bpf_map__config_value(struct bpf_map *map,
949 struct parse_events_term *term) 998 struct parse_events_term *term)
950{ 999{
951 struct bpf_map_def def;
952 struct bpf_map_op *op; 1000 struct bpf_map_op *op;
953 const char *map_name; 1001 const char *map_name = bpf_map__name(map);
954 int err; 1002 const struct bpf_map_def *def = bpf_map__def(map);
955 1003
956 map_name = bpf_map__get_name(map); 1004 if (IS_ERR(def)) {
957
958 err = bpf_map__get_def(map, &def);
959 if (err) {
960 pr_debug("Unable to get map definition from '%s'\n", 1005 pr_debug("Unable to get map definition from '%s'\n",
961 map_name); 1006 map_name);
962 return -BPF_LOADER_ERRNO__INTERNAL; 1007 return -BPF_LOADER_ERRNO__INTERNAL;
963 } 1008 }
964 1009
965 if (def.type != BPF_MAP_TYPE_ARRAY) { 1010 if (def->type != BPF_MAP_TYPE_ARRAY) {
966 pr_debug("Map %s type is not BPF_MAP_TYPE_ARRAY\n", 1011 pr_debug("Map %s type is not BPF_MAP_TYPE_ARRAY\n",
967 map_name); 1012 map_name);
968 return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE; 1013 return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
969 } 1014 }
970 if (def.key_size < sizeof(unsigned int)) { 1015 if (def->key_size < sizeof(unsigned int)) {
971 pr_debug("Map %s has incorrect key size\n", map_name); 1016 pr_debug("Map %s has incorrect key size\n", map_name);
972 return -BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE; 1017 return -BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE;
973 } 1018 }
974 switch (def.value_size) { 1019 switch (def->value_size) {
975 case 1: 1020 case 1:
976 case 2: 1021 case 2:
977 case 4: 1022 case 4:
@@ -1014,12 +1059,10 @@ __bpf_map__config_event(struct bpf_map *map,
1014 struct perf_evlist *evlist) 1059 struct perf_evlist *evlist)
1015{ 1060{
1016 struct perf_evsel *evsel; 1061 struct perf_evsel *evsel;
1017 struct bpf_map_def def; 1062 const struct bpf_map_def *def;
1018 struct bpf_map_op *op; 1063 struct bpf_map_op *op;
1019 const char *map_name; 1064 const char *map_name = bpf_map__name(map);
1020 int err;
1021 1065
1022 map_name = bpf_map__get_name(map);
1023 evsel = perf_evlist__find_evsel_by_str(evlist, term->val.str); 1066 evsel = perf_evlist__find_evsel_by_str(evlist, term->val.str);
1024 if (!evsel) { 1067 if (!evsel) {
1025 pr_debug("Event (for '%s') '%s' doesn't exist\n", 1068 pr_debug("Event (for '%s') '%s' doesn't exist\n",
@@ -1027,18 +1070,18 @@ __bpf_map__config_event(struct bpf_map *map,
1027 return -BPF_LOADER_ERRNO__OBJCONF_MAP_NOEVT; 1070 return -BPF_LOADER_ERRNO__OBJCONF_MAP_NOEVT;
1028 } 1071 }
1029 1072
1030 err = bpf_map__get_def(map, &def); 1073 def = bpf_map__def(map);
1031 if (err) { 1074 if (IS_ERR(def)) {
1032 pr_debug("Unable to get map definition from '%s'\n", 1075 pr_debug("Unable to get map definition from '%s'\n",
1033 map_name); 1076 map_name);
1034 return err; 1077 return PTR_ERR(def);
1035 } 1078 }
1036 1079
1037 /* 1080 /*
1038 * No need to check key_size and value_size: 1081 * No need to check key_size and value_size:
1039 * kernel has already checked them. 1082 * kernel has already checked them.
1040 */ 1083 */
1041 if (def.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) { 1084 if (def->type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) {
1042 pr_debug("Map %s type is not BPF_MAP_TYPE_PERF_EVENT_ARRAY\n", 1085 pr_debug("Map %s type is not BPF_MAP_TYPE_PERF_EVENT_ARRAY\n",
1043 map_name); 1086 map_name);
1044 return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE; 1087 return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
@@ -1087,9 +1130,8 @@ config_map_indices_range_check(struct parse_events_term *term,
1087 const char *map_name) 1130 const char *map_name)
1088{ 1131{
1089 struct parse_events_array *array = &term->array; 1132 struct parse_events_array *array = &term->array;
1090 struct bpf_map_def def; 1133 const struct bpf_map_def *def;
1091 unsigned int i; 1134 unsigned int i;
1092 int err;
1093 1135
1094 if (!array->nr_ranges) 1136 if (!array->nr_ranges)
1095 return 0; 1137 return 0;
@@ -1099,8 +1141,8 @@ config_map_indices_range_check(struct parse_events_term *term,
1099 return -BPF_LOADER_ERRNO__INTERNAL; 1141 return -BPF_LOADER_ERRNO__INTERNAL;
1100 } 1142 }
1101 1143
1102 err = bpf_map__get_def(map, &def); 1144 def = bpf_map__def(map);
1103 if (err) { 1145 if (IS_ERR(def)) {
1104 pr_debug("ERROR: Unable to get map definition from '%s'\n", 1146 pr_debug("ERROR: Unable to get map definition from '%s'\n",
1105 map_name); 1147 map_name);
1106 return -BPF_LOADER_ERRNO__INTERNAL; 1148 return -BPF_LOADER_ERRNO__INTERNAL;
@@ -1111,7 +1153,7 @@ config_map_indices_range_check(struct parse_events_term *term,
1111 size_t length = array->ranges[i].length; 1153 size_t length = array->ranges[i].length;
1112 unsigned int idx = start + length - 1; 1154 unsigned int idx = start + length - 1;
1113 1155
1114 if (idx >= def.max_entries) { 1156 if (idx >= def->max_entries) {
1115 pr_debug("ERROR: index %d too large\n", idx); 1157 pr_debug("ERROR: index %d too large\n", idx);
1116 return -BPF_LOADER_ERRNO__OBJCONF_MAP_IDX2BIG; 1158 return -BPF_LOADER_ERRNO__OBJCONF_MAP_IDX2BIG;
1117 } 1159 }
@@ -1147,7 +1189,7 @@ bpf__obj_config_map(struct bpf_object *obj,
1147 goto out; 1189 goto out;
1148 } 1190 }
1149 1191
1150 map = bpf_object__get_map_by_name(obj, map_name); 1192 map = bpf_object__find_map_by_name(obj, map_name);
1151 if (!map) { 1193 if (!map) {
1152 pr_debug("ERROR: Map %s doesn't exist\n", map_name); 1194 pr_debug("ERROR: Map %s doesn't exist\n", map_name);
1153 err = -BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST; 1195 err = -BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST;
@@ -1204,14 +1246,14 @@ out:
1204} 1246}
1205 1247
1206typedef int (*map_config_func_t)(const char *name, int map_fd, 1248typedef int (*map_config_func_t)(const char *name, int map_fd,
1207 struct bpf_map_def *pdef, 1249 const struct bpf_map_def *pdef,
1208 struct bpf_map_op *op, 1250 struct bpf_map_op *op,
1209 void *pkey, void *arg); 1251 void *pkey, void *arg);
1210 1252
1211static int 1253static int
1212foreach_key_array_all(map_config_func_t func, 1254foreach_key_array_all(map_config_func_t func,
1213 void *arg, const char *name, 1255 void *arg, const char *name,
1214 int map_fd, struct bpf_map_def *pdef, 1256 int map_fd, const struct bpf_map_def *pdef,
1215 struct bpf_map_op *op) 1257 struct bpf_map_op *op)
1216{ 1258{
1217 unsigned int i; 1259 unsigned int i;
@@ -1231,7 +1273,7 @@ foreach_key_array_all(map_config_func_t func,
1231static int 1273static int
1232foreach_key_array_ranges(map_config_func_t func, void *arg, 1274foreach_key_array_ranges(map_config_func_t func, void *arg,
1233 const char *name, int map_fd, 1275 const char *name, int map_fd,
1234 struct bpf_map_def *pdef, 1276 const struct bpf_map_def *pdef,
1235 struct bpf_map_op *op) 1277 struct bpf_map_op *op)
1236{ 1278{
1237 unsigned int i, j; 1279 unsigned int i, j;
@@ -1261,15 +1303,12 @@ bpf_map_config_foreach_key(struct bpf_map *map,
1261 void *arg) 1303 void *arg)
1262{ 1304{
1263 int err, map_fd; 1305 int err, map_fd;
1264 const char *name;
1265 struct bpf_map_op *op; 1306 struct bpf_map_op *op;
1266 struct bpf_map_def def; 1307 const struct bpf_map_def *def;
1267 struct bpf_map_priv *priv; 1308 const char *name = bpf_map__name(map);
1309 struct bpf_map_priv *priv = bpf_map__priv(map);
1268 1310
1269 name = bpf_map__get_name(map); 1311 if (IS_ERR(priv)) {
1270
1271 err = bpf_map__get_private(map, (void **)&priv);
1272 if (err) {
1273 pr_debug("ERROR: failed to get private from map %s\n", name); 1312 pr_debug("ERROR: failed to get private from map %s\n", name);
1274 return -BPF_LOADER_ERRNO__INTERNAL; 1313 return -BPF_LOADER_ERRNO__INTERNAL;
1275 } 1314 }
@@ -1278,29 +1317,29 @@ bpf_map_config_foreach_key(struct bpf_map *map,
1278 return 0; 1317 return 0;
1279 } 1318 }
1280 1319
1281 err = bpf_map__get_def(map, &def); 1320 def = bpf_map__def(map);
1282 if (err) { 1321 if (IS_ERR(def)) {
1283 pr_debug("ERROR: failed to get definition from map %s\n", name); 1322 pr_debug("ERROR: failed to get definition from map %s\n", name);
1284 return -BPF_LOADER_ERRNO__INTERNAL; 1323 return -BPF_LOADER_ERRNO__INTERNAL;
1285 } 1324 }
1286 map_fd = bpf_map__get_fd(map); 1325 map_fd = bpf_map__fd(map);
1287 if (map_fd < 0) { 1326 if (map_fd < 0) {
1288 pr_debug("ERROR: failed to get fd from map %s\n", name); 1327 pr_debug("ERROR: failed to get fd from map %s\n", name);
1289 return map_fd; 1328 return map_fd;
1290 } 1329 }
1291 1330
1292 list_for_each_entry(op, &priv->ops_list, list) { 1331 list_for_each_entry(op, &priv->ops_list, list) {
1293 switch (def.type) { 1332 switch (def->type) {
1294 case BPF_MAP_TYPE_ARRAY: 1333 case BPF_MAP_TYPE_ARRAY:
1295 case BPF_MAP_TYPE_PERF_EVENT_ARRAY: 1334 case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
1296 switch (op->key_type) { 1335 switch (op->key_type) {
1297 case BPF_MAP_KEY_ALL: 1336 case BPF_MAP_KEY_ALL:
1298 err = foreach_key_array_all(func, arg, name, 1337 err = foreach_key_array_all(func, arg, name,
1299 map_fd, &def, op); 1338 map_fd, def, op);
1300 break; 1339 break;
1301 case BPF_MAP_KEY_RANGES: 1340 case BPF_MAP_KEY_RANGES:
1302 err = foreach_key_array_ranges(func, arg, name, 1341 err = foreach_key_array_ranges(func, arg, name,
1303 map_fd, &def, 1342 map_fd, def,
1304 op); 1343 op);
1305 break; 1344 break;
1306 default: 1345 default:
@@ -1410,7 +1449,7 @@ apply_config_evsel_for_key(const char *name, int map_fd, void *pkey,
1410 1449
1411static int 1450static int
1412apply_obj_config_map_for_key(const char *name, int map_fd, 1451apply_obj_config_map_for_key(const char *name, int map_fd,
1413 struct bpf_map_def *pdef __maybe_unused, 1452 const struct bpf_map_def *pdef,
1414 struct bpf_map_op *op, 1453 struct bpf_map_op *op,
1415 void *pkey, void *arg __maybe_unused) 1454 void *pkey, void *arg __maybe_unused)
1416{ 1455{
@@ -1475,9 +1514,9 @@ int bpf__apply_obj_config(void)
1475 1514
1476#define bpf__for_each_stdout_map(pos, obj, objtmp) \ 1515#define bpf__for_each_stdout_map(pos, obj, objtmp) \
1477 bpf__for_each_map(pos, obj, objtmp) \ 1516 bpf__for_each_map(pos, obj, objtmp) \
1478 if (bpf_map__get_name(pos) && \ 1517 if (bpf_map__name(pos) && \
1479 (strcmp("__bpf_stdout__", \ 1518 (strcmp("__bpf_stdout__", \
1480 bpf_map__get_name(pos)) == 0)) 1519 bpf_map__name(pos)) == 0))
1481 1520
1482int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused) 1521int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
1483{ 1522{
@@ -1489,10 +1528,9 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
1489 bool need_init = false; 1528 bool need_init = false;
1490 1529
1491 bpf__for_each_stdout_map(map, obj, tmp) { 1530 bpf__for_each_stdout_map(map, obj, tmp) {
1492 struct bpf_map_priv *priv; 1531 struct bpf_map_priv *priv = bpf_map__priv(map);
1493 1532
1494 err = bpf_map__get_private(map, (void **)&priv); 1533 if (IS_ERR(priv))
1495 if (err)
1496 return -BPF_LOADER_ERRNO__INTERNAL; 1534 return -BPF_LOADER_ERRNO__INTERNAL;
1497 1535
1498 /* 1536 /*
@@ -1520,10 +1558,9 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
1520 } 1558 }
1521 1559
1522 bpf__for_each_stdout_map(map, obj, tmp) { 1560 bpf__for_each_stdout_map(map, obj, tmp) {
1523 struct bpf_map_priv *priv; 1561 struct bpf_map_priv *priv = bpf_map__priv(map);
1524 1562
1525 err = bpf_map__get_private(map, (void **)&priv); 1563 if (IS_ERR(priv))
1526 if (err)
1527 return -BPF_LOADER_ERRNO__INTERNAL; 1564 return -BPF_LOADER_ERRNO__INTERNAL;
1528 if (priv) 1565 if (priv)
1529 continue; 1566 continue;
@@ -1533,7 +1570,7 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
1533 if (!priv) 1570 if (!priv)
1534 return -ENOMEM; 1571 return -ENOMEM;
1535 1572
1536 err = bpf_map__set_private(map, priv, bpf_map_priv__clear); 1573 err = bpf_map__set_priv(map, priv, bpf_map_priv__clear);
1537 if (err) { 1574 if (err) {
1538 bpf_map_priv__clear(map, priv); 1575 bpf_map_priv__clear(map, priv);
1539 return err; 1576 return err;
@@ -1607,7 +1644,7 @@ bpf_loader_strerror(int err, char *buf, size_t size)
1607 snprintf(buf, size, "Unknown bpf loader error %d", err); 1644 snprintf(buf, size, "Unknown bpf loader error %d", err);
1608 else 1645 else
1609 snprintf(buf, size, "%s", 1646 snprintf(buf, size, "%s",
1610 strerror_r(err, sbuf, sizeof(sbuf))); 1647 str_error_r(err, sbuf, sizeof(sbuf)));
1611 1648
1612 buf[size - 1] = '\0'; 1649 buf[size - 1] = '\0';
1613 return -1; 1650 return -1;
@@ -1677,7 +1714,7 @@ int bpf__strerror_load(struct bpf_object *obj,
1677{ 1714{
1678 bpf__strerror_head(err, buf, size); 1715 bpf__strerror_head(err, buf, size);
1679 case LIBBPF_ERRNO__KVER: { 1716 case LIBBPF_ERRNO__KVER: {
1680 unsigned int obj_kver = bpf_object__get_kversion(obj); 1717 unsigned int obj_kver = bpf_object__kversion(obj);
1681 unsigned int real_kver; 1718 unsigned int real_kver;
1682 1719
1683 if (fetch_kernel_version(&real_kver, NULL, 0)) { 1720 if (fetch_kernel_version(&real_kver, NULL, 0)) {
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 941e17275aa7..f2b737b225f2 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -46,7 +46,7 @@ struct bpf_object;
46struct parse_events_term; 46struct parse_events_term;
47#define PERF_BPF_PROBE_GROUP "perf_bpf_probe" 47#define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
48 48
49typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev, 49typedef int (*bpf_prog_iter_callback_t)(const char *group, const char *event,
50 int fd, void *arg); 50 int fd, void *arg);
51 51
52#ifdef HAVE_LIBBPF_SUPPORT 52#ifdef HAVE_LIBBPF_SUPPORT
@@ -67,8 +67,8 @@ int bpf__strerror_probe(struct bpf_object *obj, int err,
67int bpf__load(struct bpf_object *obj); 67int bpf__load(struct bpf_object *obj);
68int bpf__strerror_load(struct bpf_object *obj, int err, 68int bpf__strerror_load(struct bpf_object *obj, int err,
69 char *buf, size_t size); 69 char *buf, size_t size);
70int bpf__foreach_tev(struct bpf_object *obj, 70int bpf__foreach_event(struct bpf_object *obj,
71 bpf_prog_iter_callback_t func, void *arg); 71 bpf_prog_iter_callback_t func, void *arg);
72 72
73int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term, 73int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term,
74 struct perf_evlist *evlist, int *error_pos); 74 struct perf_evlist *evlist, int *error_pos);
@@ -107,9 +107,9 @@ static inline int bpf__unprobe(struct bpf_object *obj __maybe_unused) { return 0
107static inline int bpf__load(struct bpf_object *obj __maybe_unused) { return 0; } 107static inline int bpf__load(struct bpf_object *obj __maybe_unused) { return 0; }
108 108
109static inline int 109static inline int
110bpf__foreach_tev(struct bpf_object *obj __maybe_unused, 110bpf__foreach_event(struct bpf_object *obj __maybe_unused,
111 bpf_prog_iter_callback_t func __maybe_unused, 111 bpf_prog_iter_callback_t func __maybe_unused,
112 void *arg __maybe_unused) 112 void *arg __maybe_unused)
113{ 113{
114 return 0; 114 return 0;
115} 115}
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 67e5966503b2..5651f3c12f93 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -17,6 +17,7 @@
17#include "tool.h" 17#include "tool.h"
18#include "header.h" 18#include "header.h"
19#include "vdso.h" 19#include "vdso.h"
20#include "probe-file.h"
20 21
21 22
22static bool no_buildid_cache; 23static bool no_buildid_cache;
@@ -144,7 +145,28 @@ static int asnprintf(char **strp, size_t size, const char *fmt, ...)
144 return ret; 145 return ret;
145} 146}
146 147
147static char *build_id__filename(const char *sbuild_id, char *bf, size_t size) 148char *build_id_cache__kallsyms_path(const char *sbuild_id, char *bf,
149 size_t size)
150{
151 bool retry_old = true;
152
153 snprintf(bf, size, "%s/%s/%s/kallsyms",
154 buildid_dir, DSO__NAME_KALLSYMS, sbuild_id);
155retry:
156 if (!access(bf, F_OK))
157 return bf;
158 if (retry_old) {
159 /* Try old style kallsyms cache */
160 snprintf(bf, size, "%s/%s/%s",
161 buildid_dir, DSO__NAME_KALLSYMS, sbuild_id);
162 retry_old = false;
163 goto retry;
164 }
165
166 return NULL;
167}
168
169char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size)
148{ 170{
149 char *tmp = bf; 171 char *tmp = bf;
150 int ret = asnprintf(&bf, size, "%s/.build-id/%.2s/%s", buildid_dir, 172 int ret = asnprintf(&bf, size, "%s/.build-id/%.2s/%s", buildid_dir,
@@ -154,23 +176,107 @@ static char *build_id__filename(const char *sbuild_id, char *bf, size_t size)
154 return bf; 176 return bf;
155} 177}
156 178
179char *build_id_cache__origname(const char *sbuild_id)
180{
181 char *linkname;
182 char buf[PATH_MAX];
183 char *ret = NULL, *p;
184 size_t offs = 5; /* == strlen("../..") */
185
186 linkname = build_id_cache__linkname(sbuild_id, NULL, 0);
187 if (!linkname)
188 return NULL;
189
190 if (readlink(linkname, buf, PATH_MAX) < 0)
191 goto out;
192 /* The link should be "../..<origpath>/<sbuild_id>" */
193 p = strrchr(buf, '/'); /* Cut off the "/<sbuild_id>" */
194 if (p && (p > buf + offs)) {
195 *p = '\0';
196 if (buf[offs + 1] == '[')
197 offs++; /*
198 * This is a DSO name, like [kernel.kallsyms].
199 * Skip the first '/', since this is not the
200 * cache of a regular file.
201 */
202 ret = strdup(buf + offs); /* Skip "../..[/]" */
203 }
204out:
205 free(linkname);
206 return ret;
207}
208
209/* Check if the given build_id cache is valid on current running system */
210static bool build_id_cache__valid_id(char *sbuild_id)
211{
212 char real_sbuild_id[SBUILD_ID_SIZE] = "";
213 char *pathname;
214 int ret = 0;
215 bool result = false;
216
217 pathname = build_id_cache__origname(sbuild_id);
218 if (!pathname)
219 return false;
220
221 if (!strcmp(pathname, DSO__NAME_KALLSYMS))
222 ret = sysfs__sprintf_build_id("/", real_sbuild_id);
223 else if (pathname[0] == '/')
224 ret = filename__sprintf_build_id(pathname, real_sbuild_id);
225 else
226 ret = -EINVAL; /* Should we support other special DSO cache? */
227 if (ret >= 0)
228 result = (strcmp(sbuild_id, real_sbuild_id) == 0);
229 free(pathname);
230
231 return result;
232}
233
234static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
235{
236 return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
237}
238
157char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) 239char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)
158{ 240{
159 char build_id_hex[SBUILD_ID_SIZE]; 241 bool is_kallsyms = dso__is_kallsyms((struct dso *)dso);
242 bool is_vdso = dso__is_vdso((struct dso *)dso);
243 char sbuild_id[SBUILD_ID_SIZE];
244 char *linkname;
245 bool alloc = (bf == NULL);
246 int ret;
160 247
161 if (!dso->has_build_id) 248 if (!dso->has_build_id)
162 return NULL; 249 return NULL;
163 250
164 build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex); 251 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
165 return build_id__filename(build_id_hex, bf, size); 252 linkname = build_id_cache__linkname(sbuild_id, NULL, 0);
253 if (!linkname)
254 return NULL;
255
256 /* Check if old style build_id cache */
257 if (is_regular_file(linkname))
258 ret = asnprintf(&bf, size, "%s", linkname);
259 else
260 ret = asnprintf(&bf, size, "%s/%s", linkname,
261 build_id_cache__basename(is_kallsyms, is_vdso));
262 if (ret < 0 || (!alloc && size < (unsigned int)ret))
263 bf = NULL;
264 free(linkname);
265
266 return bf;
166} 267}
167 268
168bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size) 269bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size)
169{ 270{
170 char *id_name, *ch; 271 char *id_name = NULL, *ch;
171 struct stat sb; 272 struct stat sb;
273 char sbuild_id[SBUILD_ID_SIZE];
172 274
173 id_name = dso__build_id_filename(dso, bf, size); 275 if (!dso->has_build_id)
276 goto err;
277
278 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
279 id_name = build_id_cache__linkname(sbuild_id, NULL, 0);
174 if (!id_name) 280 if (!id_name)
175 goto err; 281 goto err;
176 if (access(id_name, F_OK)) 282 if (access(id_name, F_OK))
@@ -194,18 +300,14 @@ bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size)
194 if (ch - 3 < bf) 300 if (ch - 3 < bf)
195 goto err; 301 goto err;
196 302
303 free(id_name);
197 return strncmp(".ko", ch - 3, 3) == 0; 304 return strncmp(".ko", ch - 3, 3) == 0;
198err: 305err:
199 /*
200 * If dso__build_id_filename work, get id_name again,
201 * because id_name points to bf and is broken.
202 */
203 if (id_name)
204 id_name = dso__build_id_filename(dso, bf, size);
205 pr_err("Invalid build id: %s\n", id_name ? : 306 pr_err("Invalid build id: %s\n", id_name ? :
206 dso->long_name ? : 307 dso->long_name ? :
207 dso->short_name ? : 308 dso->short_name ? :
208 "[unknown]"); 309 "[unknown]");
310 free(id_name);
209 return false; 311 return false;
210} 312}
211 313
@@ -340,8 +442,132 @@ void disable_buildid_cache(void)
340 no_buildid_cache = true; 442 no_buildid_cache = true;
341} 443}
342 444
343static char *build_id_cache__dirname_from_path(const char *name, 445static bool lsdir_bid_head_filter(const char *name __maybe_unused,
344 bool is_kallsyms, bool is_vdso) 446 struct dirent *d __maybe_unused)
447{
448 return (strlen(d->d_name) == 2) &&
449 isxdigit(d->d_name[0]) && isxdigit(d->d_name[1]);
450}
451
452static bool lsdir_bid_tail_filter(const char *name __maybe_unused,
453 struct dirent *d __maybe_unused)
454{
455 int i = 0;
456 while (isxdigit(d->d_name[i]) && i < SBUILD_ID_SIZE - 3)
457 i++;
458 return (i == SBUILD_ID_SIZE - 3) && (d->d_name[i] == '\0');
459}
460
461struct strlist *build_id_cache__list_all(bool validonly)
462{
463 struct strlist *toplist, *linklist = NULL, *bidlist;
464 struct str_node *nd, *nd2;
465 char *topdir, *linkdir = NULL;
466 char sbuild_id[SBUILD_ID_SIZE];
467
468 /* for filename__ functions */
469 if (validonly)
470 symbol__init(NULL);
471
472 /* Open the top-level directory */
473 if (asprintf(&topdir, "%s/.build-id/", buildid_dir) < 0)
474 return NULL;
475
476 bidlist = strlist__new(NULL, NULL);
477 if (!bidlist)
478 goto out;
479
480 toplist = lsdir(topdir, lsdir_bid_head_filter);
481 if (!toplist) {
482 pr_debug("Error in lsdir(%s): %d\n", topdir, errno);
483 /* If there is no buildid cache, return an empty list */
484 if (errno == ENOENT)
485 goto out;
486 goto err_out;
487 }
488
489 strlist__for_each_entry(nd, toplist) {
490 if (asprintf(&linkdir, "%s/%s", topdir, nd->s) < 0)
491 goto err_out;
492 /* Open the lower-level directory */
493 linklist = lsdir(linkdir, lsdir_bid_tail_filter);
494 if (!linklist) {
495 pr_debug("Error in lsdir(%s): %d\n", linkdir, errno);
496 goto err_out;
497 }
498 strlist__for_each_entry(nd2, linklist) {
499 if (snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
500 nd->s, nd2->s) != SBUILD_ID_SIZE - 1)
501 goto err_out;
502 if (validonly && !build_id_cache__valid_id(sbuild_id))
503 continue;
504 if (strlist__add(bidlist, sbuild_id) < 0)
505 goto err_out;
506 }
507 strlist__delete(linklist);
508 zfree(&linkdir);
509 }
510
511out_free:
512 strlist__delete(toplist);
513out:
514 free(topdir);
515
516 return bidlist;
517
518err_out:
519 strlist__delete(linklist);
520 zfree(&linkdir);
521 strlist__delete(bidlist);
522 bidlist = NULL;
523 goto out_free;
524}
525
526static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
527{
528 size_t i;
529
530 for (i = 0; i < len; i++) {
531 if (!isxdigit(maybe_sbuild_id[i]))
532 return false;
533 }
534 return true;
535}
536
537/* Return the valid complete build-id */
538char *build_id_cache__complement(const char *incomplete_sbuild_id)
539{
540 struct strlist *bidlist;
541 struct str_node *nd, *cand = NULL;
542 char *sbuild_id = NULL;
543 size_t len = strlen(incomplete_sbuild_id);
544
545 if (len >= SBUILD_ID_SIZE ||
546 !str_is_build_id(incomplete_sbuild_id, len))
547 return NULL;
548
549 bidlist = build_id_cache__list_all(true);
550 if (!bidlist)
551 return NULL;
552
553 strlist__for_each_entry(nd, bidlist) {
554 if (strncmp(nd->s, incomplete_sbuild_id, len) != 0)
555 continue;
556 if (cand) { /* Error: There are more than 2 candidates. */
557 cand = NULL;
558 break;
559 }
560 cand = nd;
561 }
562 if (cand)
563 sbuild_id = strdup(cand->s);
564 strlist__delete(bidlist);
565
566 return sbuild_id;
567}
568
569char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
570 bool is_kallsyms, bool is_vdso)
345{ 571{
346 char *realname = (char *)name, *filename; 572 char *realname = (char *)name, *filename;
347 bool slash = is_kallsyms || is_vdso; 573 bool slash = is_kallsyms || is_vdso;
@@ -352,8 +578,9 @@ static char *build_id_cache__dirname_from_path(const char *name,
352 return NULL; 578 return NULL;
353 } 579 }
354 580
355 if (asprintf(&filename, "%s%s%s", buildid_dir, slash ? "/" : "", 581 if (asprintf(&filename, "%s%s%s%s%s", buildid_dir, slash ? "/" : "",
356 is_vdso ? DSO__NAME_VDSO : realname) < 0) 582 is_vdso ? DSO__NAME_VDSO : realname,
583 sbuild_id ? "/" : "", sbuild_id ?: "") < 0)
357 filename = NULL; 584 filename = NULL;
358 585
359 if (!slash) 586 if (!slash)
@@ -368,7 +595,7 @@ int build_id_cache__list_build_ids(const char *pathname,
368 char *dir_name; 595 char *dir_name;
369 int ret = 0; 596 int ret = 0;
370 597
371 dir_name = build_id_cache__dirname_from_path(pathname, false, false); 598 dir_name = build_id_cache__cachedir(NULL, pathname, false, false);
372 if (!dir_name) 599 if (!dir_name)
373 return -ENOMEM; 600 return -ENOMEM;
374 601
@@ -380,12 +607,36 @@ int build_id_cache__list_build_ids(const char *pathname,
380 return ret; 607 return ret;
381} 608}
382 609
610#if defined(HAVE_LIBELF_SUPPORT) && defined(HAVE_GELF_GETNOTE_SUPPORT)
611static int build_id_cache__add_sdt_cache(const char *sbuild_id,
612 const char *realname)
613{
614 struct probe_cache *cache;
615 int ret;
616
617 cache = probe_cache__new(sbuild_id);
618 if (!cache)
619 return -1;
620
621 ret = probe_cache__scan_sdt(cache, realname);
622 if (ret >= 0) {
623 pr_debug("Found %d SDTs in %s\n", ret, realname);
624 if (probe_cache__commit(cache) < 0)
625 ret = -1;
626 }
627 probe_cache__delete(cache);
628 return ret;
629}
630#else
631#define build_id_cache__add_sdt_cache(sbuild_id, realname) (0)
632#endif
633
383int build_id_cache__add_s(const char *sbuild_id, const char *name, 634int build_id_cache__add_s(const char *sbuild_id, const char *name,
384 bool is_kallsyms, bool is_vdso) 635 bool is_kallsyms, bool is_vdso)
385{ 636{
386 const size_t size = PATH_MAX; 637 const size_t size = PATH_MAX;
387 char *realname = NULL, *filename = NULL, *dir_name = NULL, 638 char *realname = NULL, *filename = NULL, *dir_name = NULL,
388 *linkname = zalloc(size), *targetname, *tmp; 639 *linkname = zalloc(size), *tmp;
389 int err = -1; 640 int err = -1;
390 641
391 if (!is_kallsyms) { 642 if (!is_kallsyms) {
@@ -394,14 +645,22 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
394 goto out_free; 645 goto out_free;
395 } 646 }
396 647
397 dir_name = build_id_cache__dirname_from_path(name, is_kallsyms, is_vdso); 648 dir_name = build_id_cache__cachedir(sbuild_id, name,
649 is_kallsyms, is_vdso);
398 if (!dir_name) 650 if (!dir_name)
399 goto out_free; 651 goto out_free;
400 652
653 /* Remove old style build-id cache */
654 if (is_regular_file(dir_name))
655 if (unlink(dir_name))
656 goto out_free;
657
401 if (mkdir_p(dir_name, 0755)) 658 if (mkdir_p(dir_name, 0755))
402 goto out_free; 659 goto out_free;
403 660
404 if (asprintf(&filename, "%s/%s", dir_name, sbuild_id) < 0) { 661 /* Save the allocated buildid dirname */
662 if (asprintf(&filename, "%s/%s", dir_name,
663 build_id_cache__basename(is_kallsyms, is_vdso)) < 0) {
405 filename = NULL; 664 filename = NULL;
406 goto out_free; 665 goto out_free;
407 } 666 }
@@ -415,7 +674,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
415 goto out_free; 674 goto out_free;
416 } 675 }
417 676
418 if (!build_id__filename(sbuild_id, linkname, size)) 677 if (!build_id_cache__linkname(sbuild_id, linkname, size))
419 goto out_free; 678 goto out_free;
420 tmp = strrchr(linkname, '/'); 679 tmp = strrchr(linkname, '/');
421 *tmp = '\0'; 680 *tmp = '\0';
@@ -424,11 +683,16 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
424 goto out_free; 683 goto out_free;
425 684
426 *tmp = '/'; 685 *tmp = '/';
427 targetname = filename + strlen(buildid_dir) - 5; 686 tmp = dir_name + strlen(buildid_dir) - 5;
428 memcpy(targetname, "../..", 5); 687 memcpy(tmp, "../..", 5);
429 688
430 if (symlink(targetname, linkname) == 0) 689 if (symlink(tmp, linkname) == 0)
431 err = 0; 690 err = 0;
691
692 /* Update SDT cache : error is just warned */
693 if (build_id_cache__add_sdt_cache(sbuild_id, realname) < 0)
694 pr_debug("Failed to update/scan SDT cache for %s\n", realname);
695
432out_free: 696out_free:
433 if (!is_kallsyms) 697 if (!is_kallsyms)
434 free(realname); 698 free(realname);
@@ -452,7 +716,7 @@ static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
452bool build_id_cache__cached(const char *sbuild_id) 716bool build_id_cache__cached(const char *sbuild_id)
453{ 717{
454 bool ret = false; 718 bool ret = false;
455 char *filename = build_id__filename(sbuild_id, NULL, 0); 719 char *filename = build_id_cache__linkname(sbuild_id, NULL, 0);
456 720
457 if (filename && !access(filename, F_OK)) 721 if (filename && !access(filename, F_OK))
458 ret = true; 722 ret = true;
@@ -471,7 +735,7 @@ int build_id_cache__remove_s(const char *sbuild_id)
471 if (filename == NULL || linkname == NULL) 735 if (filename == NULL || linkname == NULL)
472 goto out_free; 736 goto out_free;
473 737
474 if (!build_id__filename(sbuild_id, linkname, size)) 738 if (!build_id_cache__linkname(sbuild_id, linkname, size))
475 goto out_free; 739 goto out_free;
476 740
477 if (access(linkname, F_OK)) 741 if (access(linkname, F_OK))
@@ -489,7 +753,7 @@ int build_id_cache__remove_s(const char *sbuild_id)
489 tmp = strrchr(linkname, '/') + 1; 753 tmp = strrchr(linkname, '/') + 1;
490 snprintf(tmp, size - (tmp - linkname), "%s", filename); 754 snprintf(tmp, size - (tmp - linkname), "%s", filename);
491 755
492 if (unlink(linkname)) 756 if (rm_rf(linkname))
493 goto out_free; 757 goto out_free;
494 758
495 err = 0; 759 err = 0;
@@ -501,7 +765,7 @@ out_free:
501 765
502static int dso__cache_build_id(struct dso *dso, struct machine *machine) 766static int dso__cache_build_id(struct dso *dso, struct machine *machine)
503{ 767{
504 bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; 768 bool is_kallsyms = dso__is_kallsyms(dso);
505 bool is_vdso = dso__is_vdso(dso); 769 bool is_vdso = dso__is_vdso(dso);
506 const char *name = dso->long_name; 770 const char *name = dso->long_name;
507 char nm[PATH_MAX]; 771 char nm[PATH_MAX];
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 64af3e20610d..d27990610f9f 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -14,6 +14,8 @@ struct dso;
14int build_id__sprintf(const u8 *build_id, int len, char *bf); 14int build_id__sprintf(const u8 *build_id, int len, char *bf);
15int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id); 15int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id);
16int filename__sprintf_build_id(const char *pathname, char *sbuild_id); 16int filename__sprintf_build_id(const char *pathname, char *sbuild_id);
17char *build_id_cache__kallsyms_path(const char *sbuild_id, char *bf,
18 size_t size);
17 19
18char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size); 20char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size);
19bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size); 21bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size);
@@ -28,6 +30,12 @@ bool perf_session__read_build_ids(struct perf_session *session, bool with_hits);
28int perf_session__write_buildid_table(struct perf_session *session, int fd); 30int perf_session__write_buildid_table(struct perf_session *session, int fd);
29int perf_session__cache_build_ids(struct perf_session *session); 31int perf_session__cache_build_ids(struct perf_session *session);
30 32
33char *build_id_cache__origname(const char *sbuild_id);
34char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
35char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
36 bool is_kallsyms, bool is_vdso);
37struct strlist *build_id_cache__list_all(bool validonly);
38char *build_id_cache__complement(const char *incomplete_sbuild_id);
31int build_id_cache__list_build_ids(const char *pathname, 39int build_id_cache__list_build_ids(const char *pathname,
32 struct strlist **result); 40 struct strlist **result);
33bool build_id_cache__cached(const char *sbuild_id); 41bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 0d814bb74661..512c0c83fbc6 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -1,40 +1,20 @@
1#ifndef __PERF_CACHE_H 1#ifndef __PERF_CACHE_H
2#define __PERF_CACHE_H 2#define __PERF_CACHE_H
3 3
4#include <stdbool.h>
5#include "util.h"
6#include "strbuf.h" 4#include "strbuf.h"
7#include <subcmd/pager.h> 5#include <subcmd/pager.h>
8#include "../perf.h"
9#include "../ui/ui.h" 6#include "../ui/ui.h"
10 7
11#include <linux/string.h> 8#include <linux/string.h>
12 9
13#define CMD_EXEC_PATH "--exec-path" 10#define CMD_EXEC_PATH "--exec-path"
14#define CMD_PERF_DIR "--perf-dir="
15#define CMD_WORK_TREE "--work-tree="
16#define CMD_DEBUGFS_DIR "--debugfs-dir=" 11#define CMD_DEBUGFS_DIR "--debugfs-dir="
17 12
18#define PERF_DIR_ENVIRONMENT "PERF_DIR"
19#define PERF_WORK_TREE_ENVIRONMENT "PERF_WORK_TREE"
20#define EXEC_PATH_ENVIRONMENT "PERF_EXEC_PATH" 13#define EXEC_PATH_ENVIRONMENT "PERF_EXEC_PATH"
21#define DEFAULT_PERF_DIR_ENVIRONMENT ".perf"
22#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" 14#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
23#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" 15#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
24#define PERF_PAGER_ENVIRONMENT "PERF_PAGER" 16#define PERF_PAGER_ENVIRONMENT "PERF_PAGER"
25 17
26extern const char *config_exclusive_filename;
27
28typedef int (*config_fn_t)(const char *, const char *, void *);
29int perf_default_config(const char *, const char *, void *);
30int perf_config(config_fn_t fn, void *);
31int perf_config_int(const char *, const char *);
32u64 perf_config_u64(const char *, const char *);
33int perf_config_bool(const char *, const char *);
34int config_error_nonbool(const char *);
35const char *perf_config_dirname(const char *, const char *);
36const char *perf_etc_perfconfig(void);
37
38char *alias_lookup(const char *alias); 18char *alias_lookup(const char *alias);
39int split_cmdline(char *cmdline, const char ***argv); 19int split_cmdline(char *cmdline, const char ***argv);
40 20
@@ -45,9 +25,6 @@ static inline int is_absolute_path(const char *path)
45 return path[0] == '/'; 25 return path[0] == '/';
46} 26}
47 27
48char *strip_path_suffix(const char *path, const char *suffix);
49
50char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 28char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
51char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
52 29
53#endif /* __PERF_CACHE_H */ 30#endif /* __PERF_CACHE_H */
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 65e2a4f7cb4e..13e75549c440 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -94,6 +94,7 @@ struct callchain_param {
94 enum perf_call_graph_mode record_mode; 94 enum perf_call_graph_mode record_mode;
95 u32 dump_size; 95 u32 dump_size;
96 enum chain_mode mode; 96 enum chain_mode mode;
97 u16 max_stack;
97 u32 print_limit; 98 u32 print_limit;
98 double min_percent; 99 double min_percent;
99 sort_chain_func_t sort; 100 sort_chain_func_t sort;
@@ -105,6 +106,7 @@ struct callchain_param {
105}; 106};
106 107
107extern struct callchain_param callchain_param; 108extern struct callchain_param callchain_param;
109extern struct callchain_param callchain_param_default;
108 110
109struct callchain_list { 111struct callchain_list {
110 u64 ip; 112 u64 ip;
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 90aa1b46b2e5..8fdee24725a7 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -81,7 +81,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str)
81 /* 81 /*
82 * check if cgrp is already defined, if so we reuse it 82 * check if cgrp is already defined, if so we reuse it
83 */ 83 */
84 evlist__for_each(evlist, counter) { 84 evlist__for_each_entry(evlist, counter) {
85 cgrp = counter->cgrp; 85 cgrp = counter->cgrp;
86 if (!cgrp) 86 if (!cgrp)
87 continue; 87 continue;
@@ -110,7 +110,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str)
110 * if add cgroup N, then need to find event N 110 * if add cgroup N, then need to find event N
111 */ 111 */
112 n = 0; 112 n = 0;
113 evlist__for_each(evlist, counter) { 113 evlist__for_each_entry(evlist, counter) {
114 if (n == nr_cgroups) 114 if (n == nr_cgroups)
115 goto found; 115 goto found;
116 n++; 116 n++;
diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c
index 2babddaa2481..f0dcd0ee0afa 100644
--- a/tools/perf/util/cloexec.c
+++ b/tools/perf/util/cloexec.c
@@ -4,18 +4,24 @@
4#include "cloexec.h" 4#include "cloexec.h"
5#include "asm/bug.h" 5#include "asm/bug.h"
6#include "debug.h" 6#include "debug.h"
7#include <unistd.h>
8#include <asm/unistd.h>
9#include <sys/syscall.h>
7 10
8static unsigned long flag = PERF_FLAG_FD_CLOEXEC; 11static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
9 12
10#ifdef __GLIBC_PREREQ
11#if !__GLIBC_PREREQ(2, 6)
12int __weak sched_getcpu(void) 13int __weak sched_getcpu(void)
13{ 14{
15#ifdef __NR_getcpu
16 unsigned cpu;
17 int err = syscall(__NR_getcpu, &cpu, NULL, NULL);
18 if (!err)
19 return cpu;
20#else
14 errno = ENOSYS; 21 errno = ENOSYS;
22#endif
15 return -1; 23 return -1;
16} 24}
17#endif
18#endif
19 25
20static int perf_flag_probe(void) 26static int perf_flag_probe(void)
21{ 27{
@@ -58,7 +64,7 @@ static int perf_flag_probe(void)
58 64
59 WARN_ONCE(err != EINVAL && err != EBUSY, 65 WARN_ONCE(err != EINVAL && err != EBUSY,
60 "perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n", 66 "perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n",
61 err, strerror_r(err, sbuf, sizeof(sbuf))); 67 err, str_error_r(err, sbuf, sizeof(sbuf)));
62 68
63 /* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */ 69 /* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
64 while (1) { 70 while (1) {
@@ -76,7 +82,7 @@ static int perf_flag_probe(void)
76 82
77 if (WARN_ONCE(fd < 0 && err != EBUSY, 83 if (WARN_ONCE(fd < 0 && err != EBUSY,
78 "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n", 84 "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n",
79 err, strerror_r(err, sbuf, sizeof(sbuf)))) 85 err, str_error_r(err, sbuf, sizeof(sbuf))))
80 return -1; 86 return -1;
81 87
82 return 0; 88 return 0;
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 43e84aa27e4a..dbbf89b050a5 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -1,7 +1,11 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include "cache.h" 2#include "cache.h"
3#include "config.h"
4#include <stdlib.h>
5#include <stdio.h>
3#include "color.h" 6#include "color.h"
4#include <math.h> 7#include <math.h>
8#include <unistd.h>
5 9
6int perf_use_color_default = -1; 10int perf_use_color_default = -1;
7 11
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index dad7d8272168..18dae745034f 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -26,6 +26,7 @@ static FILE *config_file;
26static const char *config_file_name; 26static const char *config_file_name;
27static int config_linenr; 27static int config_linenr;
28static int config_file_eof; 28static int config_file_eof;
29static struct perf_config_set *config_set;
29 30
30const char *config_exclusive_filename; 31const char *config_exclusive_filename;
31 32
@@ -275,7 +276,8 @@ static int perf_parse_file(config_fn_t fn, void *data)
275 break; 276 break;
276 } 277 }
277 } 278 }
278 die("bad config file line %d in %s", config_linenr, config_file_name); 279 pr_err("bad config file line %d in %s\n", config_linenr, config_file_name);
280 return -1;
279} 281}
280 282
281static int parse_unit_factor(const char *end, unsigned long *val) 283static int parse_unit_factor(const char *end, unsigned long *val)
@@ -371,7 +373,7 @@ int perf_config_bool(const char *name, const char *value)
371 return !!perf_config_bool_or_int(name, value, &discard); 373 return !!perf_config_bool_or_int(name, value, &discard);
372} 374}
373 375
374const char *perf_config_dirname(const char *name, const char *value) 376static const char *perf_config_dirname(const char *name, const char *value)
375{ 377{
376 if (!name) 378 if (!name)
377 return NULL; 379 return NULL;
@@ -477,54 +479,6 @@ static int perf_config_global(void)
477 return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0); 479 return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0);
478} 480}
479 481
480int perf_config(config_fn_t fn, void *data)
481{
482 int ret = 0, found = 0;
483 const char *home = NULL;
484
485 /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
486 if (config_exclusive_filename)
487 return perf_config_from_file(fn, config_exclusive_filename, data);
488 if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
489 ret += perf_config_from_file(fn, perf_etc_perfconfig(),
490 data);
491 found += 1;
492 }
493
494 home = getenv("HOME");
495 if (perf_config_global() && home) {
496 char *user_config = strdup(mkpath("%s/.perfconfig", home));
497 struct stat st;
498
499 if (user_config == NULL) {
500 warning("Not enough memory to process %s/.perfconfig, "
501 "ignoring it.", home);
502 goto out;
503 }
504
505 if (stat(user_config, &st) < 0)
506 goto out_free;
507
508 if (st.st_uid && (st.st_uid != geteuid())) {
509 warning("File %s not owned by current user or root, "
510 "ignoring it.", user_config);
511 goto out_free;
512 }
513
514 if (!st.st_size)
515 goto out_free;
516
517 ret += perf_config_from_file(fn, user_config, data);
518 found += 1;
519out_free:
520 free(user_config);
521 }
522out:
523 if (found == 0)
524 return -1;
525 return ret;
526}
527
528static struct perf_config_section *find_section(struct list_head *sections, 482static struct perf_config_section *find_section(struct list_head *sections,
529 const char *section_name) 483 const char *section_name)
530{ 484{
@@ -609,8 +563,12 @@ static int collect_config(const char *var, const char *value,
609 struct perf_config_section *section = NULL; 563 struct perf_config_section *section = NULL;
610 struct perf_config_item *item = NULL; 564 struct perf_config_item *item = NULL;
611 struct perf_config_set *set = perf_config_set; 565 struct perf_config_set *set = perf_config_set;
612 struct list_head *sections = &set->sections; 566 struct list_head *sections;
567
568 if (set == NULL)
569 return -1;
613 570
571 sections = &set->sections;
614 key = ptr = strdup(var); 572 key = ptr = strdup(var);
615 if (!key) { 573 if (!key) {
616 pr_debug("%s: strdup failed\n", __func__); 574 pr_debug("%s: strdup failed\n", __func__);
@@ -641,22 +599,115 @@ static int collect_config(const char *var, const char *value,
641 599
642out_free: 600out_free:
643 free(key); 601 free(key);
644 perf_config_set__delete(set);
645 return -1; 602 return -1;
646} 603}
647 604
605static int perf_config_set__init(struct perf_config_set *set)
606{
607 int ret = -1;
608 const char *home = NULL;
609
610 /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
611 if (config_exclusive_filename)
612 return perf_config_from_file(collect_config, config_exclusive_filename, set);
613 if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
614 if (perf_config_from_file(collect_config, perf_etc_perfconfig(), set) < 0)
615 goto out;
616 }
617
618 home = getenv("HOME");
619 if (perf_config_global() && home) {
620 char *user_config = strdup(mkpath("%s/.perfconfig", home));
621 struct stat st;
622
623 if (user_config == NULL) {
624 warning("Not enough memory to process %s/.perfconfig, "
625 "ignoring it.", home);
626 goto out;
627 }
628
629 if (stat(user_config, &st) < 0)
630 goto out_free;
631
632 if (st.st_uid && (st.st_uid != geteuid())) {
633 warning("File %s not owned by current user or root, "
634 "ignoring it.", user_config);
635 goto out_free;
636 }
637
638 if (!st.st_size)
639 goto out_free;
640
641 ret = perf_config_from_file(collect_config, user_config, set);
642
643out_free:
644 free(user_config);
645 }
646out:
647 return ret;
648}
649
648struct perf_config_set *perf_config_set__new(void) 650struct perf_config_set *perf_config_set__new(void)
649{ 651{
650 struct perf_config_set *set = zalloc(sizeof(*set)); 652 struct perf_config_set *set = zalloc(sizeof(*set));
651 653
652 if (set) { 654 if (set) {
653 INIT_LIST_HEAD(&set->sections); 655 INIT_LIST_HEAD(&set->sections);
654 perf_config(collect_config, set); 656 if (perf_config_set__init(set) < 0) {
657 perf_config_set__delete(set);
658 set = NULL;
659 }
655 } 660 }
656 661
657 return set; 662 return set;
658} 663}
659 664
665int perf_config(config_fn_t fn, void *data)
666{
667 int ret = 0;
668 char key[BUFSIZ];
669 struct perf_config_section *section;
670 struct perf_config_item *item;
671
672 if (config_set == NULL)
673 return -1;
674
675 perf_config_set__for_each_entry(config_set, section, item) {
676 char *value = item->value;
677
678 if (value) {
679 scnprintf(key, sizeof(key), "%s.%s",
680 section->name, item->name);
681 ret = fn(key, value, data);
682 if (ret < 0) {
683 pr_err("Error: wrong config key-value pair %s=%s\n",
684 key, value);
685 break;
686 }
687 }
688 }
689
690 return ret;
691}
692
693void perf_config__init(void)
694{
695 if (config_set == NULL)
696 config_set = perf_config_set__new();
697}
698
699void perf_config__exit(void)
700{
701 perf_config_set__delete(config_set);
702 config_set = NULL;
703}
704
705void perf_config__refresh(void)
706{
707 perf_config__exit();
708 perf_config__init();
709}
710
660static void perf_config_item__delete(struct perf_config_item *item) 711static void perf_config_item__delete(struct perf_config_item *item)
661{ 712{
662 zfree(&item->name); 713 zfree(&item->name);
@@ -693,6 +744,9 @@ static void perf_config_set__purge(struct perf_config_set *set)
693 744
694void perf_config_set__delete(struct perf_config_set *set) 745void perf_config_set__delete(struct perf_config_set *set)
695{ 746{
747 if (set == NULL)
748 return;
749
696 perf_config_set__purge(set); 750 perf_config_set__purge(set);
697 free(set); 751 free(set);
698} 752}
diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h
index 22ec626ac718..6f813d46045e 100644
--- a/tools/perf/util/config.h
+++ b/tools/perf/util/config.h
@@ -20,7 +20,47 @@ struct perf_config_set {
20 struct list_head sections; 20 struct list_head sections;
21}; 21};
22 22
23extern const char *config_exclusive_filename;
24
25typedef int (*config_fn_t)(const char *, const char *, void *);
26int perf_default_config(const char *, const char *, void *);
27int perf_config(config_fn_t fn, void *);
28int perf_config_int(const char *, const char *);
29u64 perf_config_u64(const char *, const char *);
30int perf_config_bool(const char *, const char *);
31int config_error_nonbool(const char *);
32const char *perf_etc_perfconfig(void);
33
23struct perf_config_set *perf_config_set__new(void); 34struct perf_config_set *perf_config_set__new(void);
24void perf_config_set__delete(struct perf_config_set *set); 35void perf_config_set__delete(struct perf_config_set *set);
36void perf_config__init(void);
37void perf_config__exit(void);
38void perf_config__refresh(void);
39
40/**
41 * perf_config_sections__for_each - iterate thru all the sections
42 * @list: list_head instance to iterate
43 * @section: struct perf_config_section iterator
44 */
45#define perf_config_sections__for_each_entry(list, section) \
46 list_for_each_entry(section, list, node)
47
48/**
49 * perf_config_items__for_each - iterate thru all the items
50 * @list: list_head instance to iterate
51 * @item: struct perf_config_item iterator
52 */
53#define perf_config_items__for_each_entry(list, item) \
54 list_for_each_entry(item, list, node)
55
56/**
57 * perf_config_set__for_each - iterate thru all the config section-item pairs
58 * @set: evlist instance to iterate
59 * @section: struct perf_config_section iterator
60 * @item: struct perf_config_item iterator
61 */
62#define perf_config_set__for_each_entry(set, section, item) \
63 perf_config_sections__for_each_entry(&set->sections, section) \
64 perf_config_items__for_each_entry(&section->items, item)
25 65
26#endif /* __PERF_CONFIG_H */ 66#endif /* __PERF_CONFIG_H */
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 02d801670f30..2c0b52264a46 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -236,13 +236,12 @@ struct cpu_map *cpu_map__new_data(struct cpu_map_data *data)
236 236
237size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp) 237size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp)
238{ 238{
239 int i; 239#define BUFSIZE 1024
240 size_t printed = fprintf(fp, "%d cpu%s: ", 240 char buf[BUFSIZE];
241 map->nr, map->nr > 1 ? "s" : "");
242 for (i = 0; i < map->nr; ++i)
243 printed += fprintf(fp, "%s%d", i ? ", " : "", map->map[i]);
244 241
245 return printed + fprintf(fp, "\n"); 242 cpu_map__snprint(map, buf, sizeof(buf));
243 return fprintf(fp, "%s\n", buf);
244#undef BUFSIZE
246} 245}
247 246
248struct cpu_map *cpu_map__dummy_new(void) 247struct cpu_map *cpu_map__dummy_new(void)
@@ -590,12 +589,65 @@ int cpu__setup_cpunode_map(void)
590 589
591bool cpu_map__has(struct cpu_map *cpus, int cpu) 590bool cpu_map__has(struct cpu_map *cpus, int cpu)
592{ 591{
592 return cpu_map__idx(cpus, cpu) != -1;
593}
594
595int cpu_map__idx(struct cpu_map *cpus, int cpu)
596{
593 int i; 597 int i;
594 598
595 for (i = 0; i < cpus->nr; ++i) { 599 for (i = 0; i < cpus->nr; ++i) {
596 if (cpus->map[i] == cpu) 600 if (cpus->map[i] == cpu)
597 return true; 601 return i;
602 }
603
604 return -1;
605}
606
607int cpu_map__cpu(struct cpu_map *cpus, int idx)
608{
609 return cpus->map[idx];
610}
611
612size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size)
613{
614 int i, cpu, start = -1;
615 bool first = true;
616 size_t ret = 0;
617
618#define COMMA first ? "" : ","
619
620 for (i = 0; i < map->nr + 1; i++) {
621 bool last = i == map->nr;
622
623 cpu = last ? INT_MAX : map->map[i];
624
625 if (start == -1) {
626 start = i;
627 if (last) {
628 ret += snprintf(buf + ret, size - ret,
629 "%s%d", COMMA,
630 map->map[i]);
631 }
632 } else if (((i - start) != (cpu - map->map[start])) || last) {
633 int end = i - 1;
634
635 if (start == end) {
636 ret += snprintf(buf + ret, size - ret,
637 "%s%d", COMMA,
638 map->map[start]);
639 } else {
640 ret += snprintf(buf + ret, size - ret,
641 "%s%d-%d", COMMA,
642 map->map[start], map->map[end]);
643 }
644 first = false;
645 start = i;
646 }
598 } 647 }
599 648
600 return false; 649#undef COMMA
650
651 pr_debug("cpumask list: %s\n", buf);
652 return ret;
601} 653}
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 1a0a35073ce1..06bd689f5989 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -19,6 +19,7 @@ struct cpu_map *cpu_map__empty_new(int nr);
19struct cpu_map *cpu_map__dummy_new(void); 19struct cpu_map *cpu_map__dummy_new(void);
20struct cpu_map *cpu_map__new_data(struct cpu_map_data *data); 20struct cpu_map *cpu_map__new_data(struct cpu_map_data *data);
21struct cpu_map *cpu_map__read(FILE *file); 21struct cpu_map *cpu_map__read(FILE *file);
22size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size);
22size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp); 23size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
23int cpu_map__get_socket_id(int cpu); 24int cpu_map__get_socket_id(int cpu);
24int cpu_map__get_socket(struct cpu_map *map, int idx, void *data); 25int cpu_map__get_socket(struct cpu_map *map, int idx, void *data);
@@ -67,5 +68,7 @@ int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
67 int (*f)(struct cpu_map *map, int cpu, void *data), 68 int (*f)(struct cpu_map *map, int cpu, void *data),
68 void *data); 69 void *data);
69 70
71int cpu_map__cpu(struct cpu_map *cpus, int idx);
70bool cpu_map__has(struct cpu_map *cpus, int cpu); 72bool cpu_map__has(struct cpu_map *cpus, int cpu);
73int cpu_map__idx(struct cpu_map *cpus, int cpu);
71#endif /* __PERF_CPUMAP_H */ 74#endif /* __PERF_CPUMAP_H */
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 9f53020c3269..4f979bb27b6c 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -26,6 +26,7 @@
26#include "evlist.h" 26#include "evlist.h"
27#include "evsel.h" 27#include "evsel.h"
28#include "machine.h" 28#include "machine.h"
29#include "config.h"
29 30
30#define pr_N(n, fmt, ...) \ 31#define pr_N(n, fmt, ...) \
31 eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__) 32 eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__)
@@ -68,6 +69,9 @@ struct ctf_writer {
68 }; 69 };
69 struct bt_ctf_field_type *array[6]; 70 struct bt_ctf_field_type *array[6];
70 } data; 71 } data;
72 struct bt_ctf_event_class *comm_class;
73 struct bt_ctf_event_class *exit_class;
74 struct bt_ctf_event_class *fork_class;
71}; 75};
72 76
73struct convert { 77struct convert {
@@ -76,6 +80,7 @@ struct convert {
76 80
77 u64 events_size; 81 u64 events_size;
78 u64 events_count; 82 u64 events_count;
83 u64 non_sample_count;
79 84
80 /* Ordered events configured queue size. */ 85 /* Ordered events configured queue size. */
81 u64 queue_size; 86 u64 queue_size;
@@ -140,6 +145,36 @@ FUNC_VALUE_SET(s64)
140FUNC_VALUE_SET(u64) 145FUNC_VALUE_SET(u64)
141__FUNC_VALUE_SET(u64_hex, u64) 146__FUNC_VALUE_SET(u64_hex, u64)
142 147
148static int string_set_value(struct bt_ctf_field *field, const char *string);
149static __maybe_unused int
150value_set_string(struct ctf_writer *cw, struct bt_ctf_event *event,
151 const char *name, const char *string)
152{
153 struct bt_ctf_field_type *type = cw->data.string;
154 struct bt_ctf_field *field;
155 int ret = 0;
156
157 field = bt_ctf_field_create(type);
158 if (!field) {
159 pr_err("failed to create a field %s\n", name);
160 return -1;
161 }
162
163 ret = string_set_value(field, string);
164 if (ret) {
165 pr_err("failed to set value %s\n", name);
166 goto err_put_field;
167 }
168
169 ret = bt_ctf_event_set_payload(event, name, field);
170 if (ret)
171 pr_err("failed to set payload %s\n", name);
172
173err_put_field:
174 bt_ctf_field_put(field);
175 return ret;
176}
177
143static struct bt_ctf_field_type* 178static struct bt_ctf_field_type*
144get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field) 179get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
145{ 180{
@@ -731,6 +766,72 @@ static int process_sample_event(struct perf_tool *tool,
731 return cs ? 0 : -1; 766 return cs ? 0 : -1;
732} 767}
733 768
769#define __NON_SAMPLE_SET_FIELD(_name, _type, _field) \
770do { \
771 ret = value_set_##_type(cw, event, #_field, _event->_name._field);\
772 if (ret) \
773 return -1; \
774} while(0)
775
776#define __FUNC_PROCESS_NON_SAMPLE(_name, body) \
777static int process_##_name##_event(struct perf_tool *tool, \
778 union perf_event *_event, \
779 struct perf_sample *sample, \
780 struct machine *machine) \
781{ \
782 struct convert *c = container_of(tool, struct convert, tool);\
783 struct ctf_writer *cw = &c->writer; \
784 struct bt_ctf_event_class *event_class = cw->_name##_class;\
785 struct bt_ctf_event *event; \
786 struct ctf_stream *cs; \
787 int ret; \
788 \
789 c->non_sample_count++; \
790 c->events_size += _event->header.size; \
791 event = bt_ctf_event_create(event_class); \
792 if (!event) { \
793 pr_err("Failed to create an CTF event\n"); \
794 return -1; \
795 } \
796 \
797 bt_ctf_clock_set_time(cw->clock, sample->time); \
798 body \
799 cs = ctf_stream(cw, 0); \
800 if (cs) { \
801 if (is_flush_needed(cs)) \
802 ctf_stream__flush(cs); \
803 \
804 cs->count++; \
805 bt_ctf_stream_append_event(cs->stream, event); \
806 } \
807 bt_ctf_event_put(event); \
808 \
809 return perf_event__process_##_name(tool, _event, sample, machine);\
810}
811
812__FUNC_PROCESS_NON_SAMPLE(comm,
813 __NON_SAMPLE_SET_FIELD(comm, u32, pid);
814 __NON_SAMPLE_SET_FIELD(comm, u32, tid);
815 __NON_SAMPLE_SET_FIELD(comm, string, comm);
816)
817__FUNC_PROCESS_NON_SAMPLE(fork,
818 __NON_SAMPLE_SET_FIELD(fork, u32, pid);
819 __NON_SAMPLE_SET_FIELD(fork, u32, ppid);
820 __NON_SAMPLE_SET_FIELD(fork, u32, tid);
821 __NON_SAMPLE_SET_FIELD(fork, u32, ptid);
822 __NON_SAMPLE_SET_FIELD(fork, u64, time);
823)
824
825__FUNC_PROCESS_NON_SAMPLE(exit,
826 __NON_SAMPLE_SET_FIELD(fork, u32, pid);
827 __NON_SAMPLE_SET_FIELD(fork, u32, ppid);
828 __NON_SAMPLE_SET_FIELD(fork, u32, tid);
829 __NON_SAMPLE_SET_FIELD(fork, u32, ptid);
830 __NON_SAMPLE_SET_FIELD(fork, u64, time);
831)
832#undef __NON_SAMPLE_SET_FIELD
833#undef __FUNC_PROCESS_NON_SAMPLE
834
734/* If dup < 0, add a prefix. Else, add _dupl_X suffix. */ 835/* If dup < 0, add a prefix. Else, add _dupl_X suffix. */
735static char *change_name(char *name, char *orig_name, int dup) 836static char *change_name(char *name, char *orig_name, int dup)
736{ 837{
@@ -997,7 +1098,7 @@ static int setup_events(struct ctf_writer *cw, struct perf_session *session)
997 struct perf_evsel *evsel; 1098 struct perf_evsel *evsel;
998 int ret; 1099 int ret;
999 1100
1000 evlist__for_each(evlist, evsel) { 1101 evlist__for_each_entry(evlist, evsel) {
1001 ret = add_event(cw, evsel); 1102 ret = add_event(cw, evsel);
1002 if (ret) 1103 if (ret)
1003 return ret; 1104 return ret;
@@ -1005,12 +1106,86 @@ static int setup_events(struct ctf_writer *cw, struct perf_session *session)
1005 return 0; 1106 return 0;
1006} 1107}
1007 1108
1109#define __NON_SAMPLE_ADD_FIELD(t, n) \
1110 do { \
1111 pr2(" field '%s'\n", #n); \
1112 if (bt_ctf_event_class_add_field(event_class, cw->data.t, #n)) {\
1113 pr_err("Failed to add field '%s';\n", #n);\
1114 return -1; \
1115 } \
1116 } while(0)
1117
1118#define __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(_name, body) \
1119static int add_##_name##_event(struct ctf_writer *cw) \
1120{ \
1121 struct bt_ctf_event_class *event_class; \
1122 int ret; \
1123 \
1124 pr("Adding "#_name" event\n"); \
1125 event_class = bt_ctf_event_class_create("perf_" #_name);\
1126 if (!event_class) \
1127 return -1; \
1128 body \
1129 \
1130 ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);\
1131 if (ret) { \
1132 pr("Failed to add event class '"#_name"' into stream.\n");\
1133 return ret; \
1134 } \
1135 \
1136 cw->_name##_class = event_class; \
1137 bt_ctf_event_class_put(event_class); \
1138 return 0; \
1139}
1140
1141__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(comm,
1142 __NON_SAMPLE_ADD_FIELD(u32, pid);
1143 __NON_SAMPLE_ADD_FIELD(u32, tid);
1144 __NON_SAMPLE_ADD_FIELD(string, comm);
1145)
1146
1147__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(fork,
1148 __NON_SAMPLE_ADD_FIELD(u32, pid);
1149 __NON_SAMPLE_ADD_FIELD(u32, ppid);
1150 __NON_SAMPLE_ADD_FIELD(u32, tid);
1151 __NON_SAMPLE_ADD_FIELD(u32, ptid);
1152 __NON_SAMPLE_ADD_FIELD(u64, time);
1153)
1154
1155__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(exit,
1156 __NON_SAMPLE_ADD_FIELD(u32, pid);
1157 __NON_SAMPLE_ADD_FIELD(u32, ppid);
1158 __NON_SAMPLE_ADD_FIELD(u32, tid);
1159 __NON_SAMPLE_ADD_FIELD(u32, ptid);
1160 __NON_SAMPLE_ADD_FIELD(u64, time);
1161)
1162
1163#undef __NON_SAMPLE_ADD_FIELD
1164#undef __FUNC_ADD_NON_SAMPLE_EVENT_CLASS
1165
1166static int setup_non_sample_events(struct ctf_writer *cw,
1167 struct perf_session *session __maybe_unused)
1168{
1169 int ret;
1170
1171 ret = add_comm_event(cw);
1172 if (ret)
1173 return ret;
1174 ret = add_exit_event(cw);
1175 if (ret)
1176 return ret;
1177 ret = add_fork_event(cw);
1178 if (ret)
1179 return ret;
1180 return 0;
1181}
1182
1008static void cleanup_events(struct perf_session *session) 1183static void cleanup_events(struct perf_session *session)
1009{ 1184{
1010 struct perf_evlist *evlist = session->evlist; 1185 struct perf_evlist *evlist = session->evlist;
1011 struct perf_evsel *evsel; 1186 struct perf_evsel *evsel;
1012 1187
1013 evlist__for_each(evlist, evsel) { 1188 evlist__for_each_entry(evlist, evsel) {
1014 struct evsel_priv *priv; 1189 struct evsel_priv *priv;
1015 1190
1016 priv = evsel->priv; 1191 priv = evsel->priv;
@@ -1273,13 +1448,14 @@ static int convert__config(const char *var, const char *value, void *cb)
1273 return 0; 1448 return 0;
1274} 1449}
1275 1450
1276int bt_convert__perf2ctf(const char *input, const char *path, bool force) 1451int bt_convert__perf2ctf(const char *input, const char *path,
1452 struct perf_data_convert_opts *opts)
1277{ 1453{
1278 struct perf_session *session; 1454 struct perf_session *session;
1279 struct perf_data_file file = { 1455 struct perf_data_file file = {
1280 .path = input, 1456 .path = input,
1281 .mode = PERF_DATA_MODE_READ, 1457 .mode = PERF_DATA_MODE_READ,
1282 .force = force, 1458 .force = opts->force,
1283 }; 1459 };
1284 struct convert c = { 1460 struct convert c = {
1285 .tool = { 1461 .tool = {
@@ -1299,6 +1475,12 @@ int bt_convert__perf2ctf(const char *input, const char *path, bool force)
1299 struct ctf_writer *cw = &c.writer; 1475 struct ctf_writer *cw = &c.writer;
1300 int err = -1; 1476 int err = -1;
1301 1477
1478 if (opts->all) {
1479 c.tool.comm = process_comm_event;
1480 c.tool.exit = process_exit_event;
1481 c.tool.fork = process_fork_event;
1482 }
1483
1302 perf_config(convert__config, &c); 1484 perf_config(convert__config, &c);
1303 1485
1304 /* CTF writer */ 1486 /* CTF writer */
@@ -1323,6 +1505,9 @@ int bt_convert__perf2ctf(const char *input, const char *path, bool force)
1323 if (setup_events(cw, session)) 1505 if (setup_events(cw, session))
1324 goto free_session; 1506 goto free_session;
1325 1507
1508 if (opts->all && setup_non_sample_events(cw, session))
1509 goto free_session;
1510
1326 if (setup_streams(cw, session)) 1511 if (setup_streams(cw, session))
1327 goto free_session; 1512 goto free_session;
1328 1513
@@ -1337,10 +1522,15 @@ int bt_convert__perf2ctf(const char *input, const char *path, bool force)
1337 file.path, path); 1522 file.path, path);
1338 1523
1339 fprintf(stderr, 1524 fprintf(stderr,
1340 "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples) ]\n", 1525 "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples",
1341 (double) c.events_size / 1024.0 / 1024.0, 1526 (double) c.events_size / 1024.0 / 1024.0,
1342 c.events_count); 1527 c.events_count);
1343 1528
1529 if (!c.non_sample_count)
1530 fprintf(stderr, ") ]\n");
1531 else
1532 fprintf(stderr, ", %" PRIu64 " non-samples) ]\n", c.non_sample_count);
1533
1344 cleanup_events(session); 1534 cleanup_events(session);
1345 perf_session__delete(session); 1535 perf_session__delete(session);
1346 ctf_writer__cleanup(cw); 1536 ctf_writer__cleanup(cw);
diff --git a/tools/perf/util/data-convert-bt.h b/tools/perf/util/data-convert-bt.h
index 4c204342a9d8..9a3b587f76c1 100644
--- a/tools/perf/util/data-convert-bt.h
+++ b/tools/perf/util/data-convert-bt.h
@@ -1,8 +1,10 @@
1#ifndef __DATA_CONVERT_BT_H 1#ifndef __DATA_CONVERT_BT_H
2#define __DATA_CONVERT_BT_H 2#define __DATA_CONVERT_BT_H
3#include "data-convert.h"
3#ifdef HAVE_LIBBABELTRACE_SUPPORT 4#ifdef HAVE_LIBBABELTRACE_SUPPORT
4 5
5int bt_convert__perf2ctf(const char *input_name, const char *to_ctf, bool force); 6int bt_convert__perf2ctf(const char *input_name, const char *to_ctf,
7 struct perf_data_convert_opts *opts);
6 8
7#endif /* HAVE_LIBBABELTRACE_SUPPORT */ 9#endif /* HAVE_LIBBABELTRACE_SUPPORT */
8#endif /* __DATA_CONVERT_BT_H */ 10#endif /* __DATA_CONVERT_BT_H */
diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h
new file mode 100644
index 000000000000..5314962fe95b
--- /dev/null
+++ b/tools/perf/util/data-convert.h
@@ -0,0 +1,9 @@
1#ifndef __DATA_CONVERT_H
2#define __DATA_CONVERT_H
3
4struct perf_data_convert_opts {
5 bool force;
6 bool all;
7};
8
9#endif /* __DATA_CONVERT_H */
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index be83516155ee..60bfc9ca1e22 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -57,7 +57,7 @@ static int open_file_read(struct perf_data_file *file)
57 int err = errno; 57 int err = errno;
58 58
59 pr_err("failed to open %s: %s", file->path, 59 pr_err("failed to open %s: %s", file->path,
60 strerror_r(err, sbuf, sizeof(sbuf))); 60 str_error_r(err, sbuf, sizeof(sbuf)));
61 if (err == ENOENT && !strcmp(file->path, "perf.data")) 61 if (err == ENOENT && !strcmp(file->path, "perf.data"))
62 pr_err(" (try 'perf record' first)"); 62 pr_err(" (try 'perf record' first)");
63 pr_err("\n"); 63 pr_err("\n");
@@ -99,7 +99,7 @@ static int open_file_write(struct perf_data_file *file)
99 99
100 if (fd < 0) 100 if (fd < 0)
101 pr_err("failed to open %s : %s\n", file->path, 101 pr_err("failed to open %s : %s\n", file->path,
102 strerror_r(errno, sbuf, sizeof(sbuf))); 102 str_error_r(errno, sbuf, sizeof(sbuf)));
103 103
104 return fd; 104 return fd;
105} 105}
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
index c9a6dc173e74..b0c2b5c5d337 100644
--- a/tools/perf/util/db-export.c
+++ b/tools/perf/util/db-export.c
@@ -233,17 +233,6 @@ int db_export__symbol(struct db_export *dbe, struct symbol *sym,
233 return 0; 233 return 0;
234} 234}
235 235
236static struct thread *get_main_thread(struct machine *machine, struct thread *thread)
237{
238 if (thread->pid_ == thread->tid)
239 return thread__get(thread);
240
241 if (thread->pid_ == -1)
242 return NULL;
243
244 return machine__find_thread(machine, thread->pid_, thread->pid_);
245}
246
247static int db_ids_from_al(struct db_export *dbe, struct addr_location *al, 236static int db_ids_from_al(struct db_export *dbe, struct addr_location *al,
248 u64 *dso_db_id, u64 *sym_db_id, u64 *offset) 237 u64 *dso_db_id, u64 *sym_db_id, u64 *offset)
249{ 238{
@@ -382,7 +371,7 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
382 if (err) 371 if (err)
383 return err; 372 return err;
384 373
385 main_thread = get_main_thread(al->machine, thread); 374 main_thread = thread__main_thread(al->machine, thread);
386 if (main_thread) 375 if (main_thread)
387 comm = machine__thread_exec_comm(al->machine, main_thread); 376 comm = machine__thread_exec_comm(al->machine, main_thread);
388 377
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 14bafda79eda..d242adc3d5a2 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -38,7 +38,7 @@ extern int debug_data_convert;
38#define pr_oe_time(t, fmt, ...) pr_time_N(1, debug_ordered_events, t, pr_fmt(fmt), ##__VA_ARGS__) 38#define pr_oe_time(t, fmt, ...) pr_time_N(1, debug_ordered_events, t, pr_fmt(fmt), ##__VA_ARGS__)
39#define pr_oe_time2(t, fmt, ...) pr_time_N(2, debug_ordered_events, t, pr_fmt(fmt), ##__VA_ARGS__) 39#define pr_oe_time2(t, fmt, ...) pr_time_N(2, debug_ordered_events, t, pr_fmt(fmt), ##__VA_ARGS__)
40 40
41#define STRERR_BUFSIZE 128 /* For the buffer size of strerror_r */ 41#define STRERR_BUFSIZE 128 /* For the buffer size of str_error_r */
42 42
43int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); 43int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
44void trace_event(union perf_event *event); 44void trace_event(union perf_event *event);
diff --git a/tools/perf/util/demangle-rust.c b/tools/perf/util/demangle-rust.c
new file mode 100644
index 000000000000..f9dafa888c06
--- /dev/null
+++ b/tools/perf/util/demangle-rust.c
@@ -0,0 +1,269 @@
1#include <string.h>
2#include "util.h"
3#include "debug.h"
4
5#include "demangle-rust.h"
6
7/*
8 * Mangled Rust symbols look like this:
9 *
10 * _$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
11 *
12 * The original symbol is:
13 *
14 * <std::sys::fd::FileDesc as core::ops::Drop>::drop
15 *
16 * The last component of the path is a 64-bit hash in lowercase hex, prefixed
17 * with "h". Rust does not have a global namespace between crates, an illusion
18 * which Rust maintains by using the hash to distinguish things that would
19 * otherwise have the same symbol.
20 *
21 * Any path component not starting with a XID_Start character is prefixed with
22 * "_".
23 *
24 * The following escape sequences are used:
25 *
26 * "," => $C$
27 * "@" => $SP$
28 * "*" => $BP$
29 * "&" => $RF$
30 * "<" => $LT$
31 * ">" => $GT$
32 * "(" => $LP$
33 * ")" => $RP$
34 * " " => $u20$
35 * "'" => $u27$
36 * "[" => $u5b$
37 * "]" => $u5d$
38 * "~" => $u7e$
39 *
40 * A double ".." means "::" and a single "." means "-".
41 *
42 * The only characters allowed in the mangled symbol are a-zA-Z0-9 and _.:$
43 */
44
45static const char *hash_prefix = "::h";
46static const size_t hash_prefix_len = 3;
47static const size_t hash_len = 16;
48
49static bool is_prefixed_hash(const char *start);
50static bool looks_like_rust(const char *sym, size_t len);
51static bool unescape(const char **in, char **out, const char *seq, char value);
52
53/*
54 * INPUT:
55 * sym: symbol that has been through BFD-demangling
56 *
57 * This function looks for the following indicators:
58 *
59 * 1. The hash must consist of "h" followed by 16 lowercase hex digits.
60 *
61 * 2. As a sanity check, the hash must use between 5 and 15 of the 16 possible
62 * hex digits. This is true of 99.9998% of hashes so once in your life you
63 * may see a false negative. The point is to notice path components that
64 * could be Rust hashes but are probably not, like "haaaaaaaaaaaaaaaa". In
65 * this case a false positive (non-Rust symbol has an important path
66 * component removed because it looks like a Rust hash) is worse than a
67 * false negative (the rare Rust symbol is not demangled) so this sets the
68 * balance in favor of false negatives.
69 *
70 * 3. There must be no characters other than a-zA-Z0-9 and _.:$
71 *
72 * 4. There must be no unrecognized $-sign sequences.
73 *
74 * 5. There must be no sequence of three or more dots in a row ("...").
75 */
76bool
77rust_is_mangled(const char *sym)
78{
79 size_t len, len_without_hash;
80
81 if (!sym)
82 return false;
83
84 len = strlen(sym);
85 if (len <= hash_prefix_len + hash_len)
86 /* Not long enough to contain "::h" + hash + something else */
87 return false;
88
89 len_without_hash = len - (hash_prefix_len + hash_len);
90 if (!is_prefixed_hash(sym + len_without_hash))
91 return false;
92
93 return looks_like_rust(sym, len_without_hash);
94}
95
96/*
97 * A hash is the prefix "::h" followed by 16 lowercase hex digits. The hex
98 * digits must comprise between 5 and 15 (inclusive) distinct digits.
99 */
100static bool is_prefixed_hash(const char *str)
101{
102 const char *end;
103 bool seen[16];
104 size_t i;
105 int count;
106
107 if (strncmp(str, hash_prefix, hash_prefix_len))
108 return false;
109 str += hash_prefix_len;
110
111 memset(seen, false, sizeof(seen));
112 for (end = str + hash_len; str < end; str++)
113 if (*str >= '0' && *str <= '9')
114 seen[*str - '0'] = true;
115 else if (*str >= 'a' && *str <= 'f')
116 seen[*str - 'a' + 10] = true;
117 else
118 return false;
119
120 /* Count how many distinct digits seen */
121 count = 0;
122 for (i = 0; i < 16; i++)
123 if (seen[i])
124 count++;
125
126 return count >= 5 && count <= 15;
127}
128
129static bool looks_like_rust(const char *str, size_t len)
130{
131 const char *end = str + len;
132
133 while (str < end)
134 switch (*str) {
135 case '$':
136 if (!strncmp(str, "$C$", 3))
137 str += 3;
138 else if (!strncmp(str, "$SP$", 4)
139 || !strncmp(str, "$BP$", 4)
140 || !strncmp(str, "$RF$", 4)
141 || !strncmp(str, "$LT$", 4)
142 || !strncmp(str, "$GT$", 4)
143 || !strncmp(str, "$LP$", 4)
144 || !strncmp(str, "$RP$", 4))
145 str += 4;
146 else if (!strncmp(str, "$u20$", 5)
147 || !strncmp(str, "$u27$", 5)
148 || !strncmp(str, "$u5b$", 5)
149 || !strncmp(str, "$u5d$", 5)
150 || !strncmp(str, "$u7e$", 5))
151 str += 5;
152 else
153 return false;
154 break;
155 case '.':
156 /* Do not allow three or more consecutive dots */
157 if (!strncmp(str, "...", 3))
158 return false;
159 /* Fall through */
160 case 'a' ... 'z':
161 case 'A' ... 'Z':
162 case '0' ... '9':
163 case '_':
164 case ':':
165 str++;
166 break;
167 default:
168 return false;
169 }
170
171 return true;
172}
173
174/*
175 * INPUT:
176 * sym: symbol for which rust_is_mangled(sym) returns true
177 *
178 * The input is demangled in-place because the mangled name is always longer
179 * than the demangled one.
180 */
181void
182rust_demangle_sym(char *sym)
183{
184 const char *in;
185 char *out;
186 const char *end;
187
188 if (!sym)
189 return;
190
191 in = sym;
192 out = sym;
193 end = sym + strlen(sym) - (hash_prefix_len + hash_len);
194
195 while (in < end)
196 switch (*in) {
197 case '$':
198 if (!(unescape(&in, &out, "$C$", ',')
199 || unescape(&in, &out, "$SP$", '@')
200 || unescape(&in, &out, "$BP$", '*')
201 || unescape(&in, &out, "$RF$", '&')
202 || unescape(&in, &out, "$LT$", '<')
203 || unescape(&in, &out, "$GT$", '>')
204 || unescape(&in, &out, "$LP$", '(')
205 || unescape(&in, &out, "$RP$", ')')
206 || unescape(&in, &out, "$u20$", ' ')
207 || unescape(&in, &out, "$u27$", '\'')
208 || unescape(&in, &out, "$u5b$", '[')
209 || unescape(&in, &out, "$u5d$", ']')
210 || unescape(&in, &out, "$u7e$", '~'))) {
211 pr_err("demangle-rust: unexpected escape sequence");
212 goto done;
213 }
214 break;
215 case '_':
216 /*
217 * If this is the start of a path component and the next
218 * character is an escape sequence, ignore the
219 * underscore. The mangler inserts an underscore to make
220 * sure the path component begins with a XID_Start
221 * character.
222 */
223 if ((in == sym || in[-1] == ':') && in[1] == '$')
224 in++;
225 else
226 *out++ = *in++;
227 break;
228 case '.':
229 if (in[1] == '.') {
230 /* ".." becomes "::" */
231 *out++ = ':';
232 *out++ = ':';
233 in += 2;
234 } else {
235 /* "." becomes "-" */
236 *out++ = '-';
237 in++;
238 }
239 break;
240 case 'a' ... 'z':
241 case 'A' ... 'Z':
242 case '0' ... '9':
243 case ':':
244 *out++ = *in++;
245 break;
246 default:
247 pr_err("demangle-rust: unexpected character '%c' in symbol\n",
248 *in);
249 goto done;
250 }
251
252done:
253 *out = '\0';
254}
255
256static bool unescape(const char **in, char **out, const char *seq, char value)
257{
258 size_t len = strlen(seq);
259
260 if (strncmp(*in, seq, len))
261 return false;
262
263 **out = value;
264
265 *in += len;
266 *out += 1;
267
268 return true;
269}
diff --git a/tools/perf/util/demangle-rust.h b/tools/perf/util/demangle-rust.h
new file mode 100644
index 000000000000..7b41ead7e0dd
--- /dev/null
+++ b/tools/perf/util/demangle-rust.h
@@ -0,0 +1,7 @@
1#ifndef __PERF_DEMANGLE_RUST
2#define __PERF_DEMANGLE_RUST 1
3
4bool rust_is_mangled(const char *str);
5void rust_demangle_sym(char *str);
6
7#endif /* __PERF_DEMANGLE_RUST */
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 5d286f5d7906..774f6ec884d5 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -335,7 +335,7 @@ static int do_open(char *name)
335 return fd; 335 return fd;
336 336
337 pr_debug("dso open failed: %s\n", 337 pr_debug("dso open failed: %s\n",
338 strerror_r(errno, sbuf, sizeof(sbuf))); 338 str_error_r(errno, sbuf, sizeof(sbuf)));
339 if (!dso__data_open_cnt || errno != EMFILE) 339 if (!dso__data_open_cnt || errno != EMFILE)
340 break; 340 break;
341 341
@@ -442,17 +442,27 @@ static rlim_t get_fd_limit(void)
442 return limit; 442 return limit;
443} 443}
444 444
445static bool may_cache_fd(void) 445static rlim_t fd_limit;
446
447/*
448 * Used only by tests/dso-data.c to reset the environment
449 * for tests. I dont expect we should change this during
450 * standard runtime.
451 */
452void reset_fd_limit(void)
446{ 453{
447 static rlim_t limit; 454 fd_limit = 0;
455}
448 456
449 if (!limit) 457static bool may_cache_fd(void)
450 limit = get_fd_limit(); 458{
459 if (!fd_limit)
460 fd_limit = get_fd_limit();
451 461
452 if (limit == RLIM_INFINITY) 462 if (fd_limit == RLIM_INFINITY)
453 return true; 463 return true;
454 464
455 return limit > (rlim_t) dso__data_open_cnt; 465 return fd_limit > (rlim_t) dso__data_open_cnt;
456} 466}
457 467
458/* 468/*
@@ -776,7 +786,7 @@ static int data_file_size(struct dso *dso, struct machine *machine)
776 if (fstat(dso->data.fd, &st) < 0) { 786 if (fstat(dso->data.fd, &st) < 0) {
777 ret = -errno; 787 ret = -errno;
778 pr_err("dso cache fstat failed: %s\n", 788 pr_err("dso cache fstat failed: %s\n",
779 strerror_r(errno, sbuf, sizeof(sbuf))); 789 str_error_r(errno, sbuf, sizeof(sbuf)));
780 dso->data.status = DSO_DATA_STATUS_ERROR; 790 dso->data.status = DSO_DATA_STATUS_ERROR;
781 goto out; 791 goto out;
782 } 792 }
@@ -1356,7 +1366,7 @@ int dso__strerror_load(struct dso *dso, char *buf, size_t buflen)
1356 BUG_ON(buflen == 0); 1366 BUG_ON(buflen == 0);
1357 1367
1358 if (errnum >= 0) { 1368 if (errnum >= 0) {
1359 const char *err = strerror_r(errnum, buf, buflen); 1369 const char *err = str_error_r(errnum, buf, buflen);
1360 1370
1361 if (err != buf) 1371 if (err != buf)
1362 scnprintf(buf, buflen, "%s", err); 1372 scnprintf(buf, buflen, "%s", err);
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 0953280629cf..ecc4bbd3f82e 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -4,6 +4,7 @@
4#include <linux/atomic.h> 4#include <linux/atomic.h>
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/rbtree.h> 6#include <linux/rbtree.h>
7#include <sys/types.h>
7#include <stdbool.h> 8#include <stdbool.h>
8#include <pthread.h> 9#include <pthread.h>
9#include <linux/types.h> 10#include <linux/types.h>
@@ -349,10 +350,17 @@ static inline bool dso__is_kcore(struct dso *dso)
349 dso->binary_type == DSO_BINARY_TYPE__GUEST_KCORE; 350 dso->binary_type == DSO_BINARY_TYPE__GUEST_KCORE;
350} 351}
351 352
353static inline bool dso__is_kallsyms(struct dso *dso)
354{
355 return dso->kernel && dso->long_name[0] != '/';
356}
357
352void dso__free_a2l(struct dso *dso); 358void dso__free_a2l(struct dso *dso);
353 359
354enum dso_type dso__type(struct dso *dso, struct machine *machine); 360enum dso_type dso__type(struct dso *dso, struct machine *machine);
355 361
356int dso__strerror_load(struct dso *dso, char *buf, size_t buflen); 362int dso__strerror_load(struct dso *dso, char *buf, size_t buflen);
357 363
364void reset_fd_limit(void);
365
358#endif /* __PERF_DSO */ 366#endif /* __PERF_DSO */
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 49a11d9d8b8f..bb964e86b09d 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -18,10 +18,13 @@ void perf_env__exit(struct perf_env *env)
18 zfree(&env->cmdline_argv); 18 zfree(&env->cmdline_argv);
19 zfree(&env->sibling_cores); 19 zfree(&env->sibling_cores);
20 zfree(&env->sibling_threads); 20 zfree(&env->sibling_threads);
21 zfree(&env->numa_nodes);
22 zfree(&env->pmu_mappings); 21 zfree(&env->pmu_mappings);
23 zfree(&env->cpu); 22 zfree(&env->cpu);
24 23
24 for (i = 0; i < env->nr_numa_nodes; i++)
25 cpu_map__put(env->numa_nodes[i].map);
26 zfree(&env->numa_nodes);
27
25 for (i = 0; i < env->caches_cnt; i++) 28 for (i = 0; i < env->caches_cnt; i++)
26 cpu_cache_level__free(&env->caches[i]); 29 cpu_cache_level__free(&env->caches[i]);
27 zfree(&env->caches); 30 zfree(&env->caches);
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 56cffb60a0b4..b164dfd2dcbf 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -2,6 +2,7 @@
2#define __PERF_ENV_H 2#define __PERF_ENV_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include "cpumap.h"
5 6
6struct cpu_topology_map { 7struct cpu_topology_map {
7 int socket_id; 8 int socket_id;
@@ -18,6 +19,13 @@ struct cpu_cache_level {
18 char *map; 19 char *map;
19}; 20};
20 21
22struct numa_node {
23 u32 node;
24 u64 mem_total;
25 u64 mem_free;
26 struct cpu_map *map;
27};
28
21struct perf_env { 29struct perf_env {
22 char *hostname; 30 char *hostname;
23 char *os_release; 31 char *os_release;
@@ -40,11 +48,11 @@ struct perf_env {
40 const char **cmdline_argv; 48 const char **cmdline_argv;
41 char *sibling_cores; 49 char *sibling_cores;
42 char *sibling_threads; 50 char *sibling_threads;
43 char *numa_nodes;
44 char *pmu_mappings; 51 char *pmu_mappings;
45 struct cpu_topology_map *cpu; 52 struct cpu_topology_map *cpu;
46 struct cpu_cache_level *caches; 53 struct cpu_cache_level *caches;
47 int caches_cnt; 54 int caches_cnt;
55 struct numa_node *numa_nodes;
48}; 56};
49 57
50extern struct perf_env perf_env; 58extern struct perf_env perf_env;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 9b141f12329e..e20438b784be 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1092,7 +1092,7 @@ size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp)
1092 struct cpu_map *cpus = cpu_map__new_data(&event->cpu_map.data); 1092 struct cpu_map *cpus = cpu_map__new_data(&event->cpu_map.data);
1093 size_t ret; 1093 size_t ret;
1094 1094
1095 ret = fprintf(fp, " nr: "); 1095 ret = fprintf(fp, ": ");
1096 1096
1097 if (cpus) 1097 if (cpus)
1098 ret += cpu_map__fprintf(cpus, fp); 1098 ret += cpu_map__fprintf(cpus, fp);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index e82ba90cc969..2a40b8e1def7 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -15,6 +15,7 @@
15#include "evlist.h" 15#include "evlist.h"
16#include "evsel.h" 16#include "evsel.h"
17#include "debug.h" 17#include "debug.h"
18#include "asm/bug.h"
18#include <unistd.h> 19#include <unistd.h>
19 20
20#include "parse-events.h" 21#include "parse-events.h"
@@ -27,8 +28,8 @@
27#include <linux/log2.h> 28#include <linux/log2.h>
28#include <linux/err.h> 29#include <linux/err.h>
29 30
30static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); 31static void perf_mmap__munmap(struct perf_mmap *map);
31static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); 32static void perf_mmap__put(struct perf_mmap *map);
32 33
33#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 34#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
34#define SID(e, x, y) xyarray__entry(e->sample_id, x, y) 35#define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
@@ -44,7 +45,7 @@ void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
44 perf_evlist__set_maps(evlist, cpus, threads); 45 perf_evlist__set_maps(evlist, cpus, threads);
45 fdarray__init(&evlist->pollfd, 64); 46 fdarray__init(&evlist->pollfd, 64);
46 evlist->workload.pid = -1; 47 evlist->workload.pid = -1;
47 evlist->backward = false; 48 evlist->bkw_mmap_state = BKW_MMAP_NOTREADY;
48} 49}
49 50
50struct perf_evlist *perf_evlist__new(void) 51struct perf_evlist *perf_evlist__new(void)
@@ -100,7 +101,7 @@ static void perf_evlist__update_id_pos(struct perf_evlist *evlist)
100{ 101{
101 struct perf_evsel *evsel; 102 struct perf_evsel *evsel;
102 103
103 evlist__for_each(evlist, evsel) 104 evlist__for_each_entry(evlist, evsel)
104 perf_evsel__calc_id_pos(evsel); 105 perf_evsel__calc_id_pos(evsel);
105 106
106 perf_evlist__set_id_pos(evlist); 107 perf_evlist__set_id_pos(evlist);
@@ -110,7 +111,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
110{ 111{
111 struct perf_evsel *pos, *n; 112 struct perf_evsel *pos, *n;
112 113
113 evlist__for_each_safe(evlist, n, pos) { 114 evlist__for_each_entry_safe(evlist, n, pos) {
114 list_del_init(&pos->node); 115 list_del_init(&pos->node);
115 pos->evlist = NULL; 116 pos->evlist = NULL;
116 perf_evsel__delete(pos); 117 perf_evsel__delete(pos);
@@ -122,11 +123,15 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
122void perf_evlist__exit(struct perf_evlist *evlist) 123void perf_evlist__exit(struct perf_evlist *evlist)
123{ 124{
124 zfree(&evlist->mmap); 125 zfree(&evlist->mmap);
126 zfree(&evlist->backward_mmap);
125 fdarray__exit(&evlist->pollfd); 127 fdarray__exit(&evlist->pollfd);
126} 128}
127 129
128void perf_evlist__delete(struct perf_evlist *evlist) 130void perf_evlist__delete(struct perf_evlist *evlist)
129{ 131{
132 if (evlist == NULL)
133 return;
134
130 perf_evlist__munmap(evlist); 135 perf_evlist__munmap(evlist);
131 perf_evlist__close(evlist); 136 perf_evlist__close(evlist);
132 cpu_map__put(evlist->cpus); 137 cpu_map__put(evlist->cpus);
@@ -161,7 +166,7 @@ static void perf_evlist__propagate_maps(struct perf_evlist *evlist)
161{ 166{
162 struct perf_evsel *evsel; 167 struct perf_evsel *evsel;
163 168
164 evlist__for_each(evlist, evsel) 169 evlist__for_each_entry(evlist, evsel)
165 __perf_evlist__propagate_maps(evlist, evsel); 170 __perf_evlist__propagate_maps(evlist, evsel);
166} 171}
167 172
@@ -190,7 +195,7 @@ void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
190{ 195{
191 struct perf_evsel *evsel, *temp; 196 struct perf_evsel *evsel, *temp;
192 197
193 __evlist__for_each_safe(list, temp, evsel) { 198 __evlist__for_each_entry_safe(list, temp, evsel) {
194 list_del_init(&evsel->node); 199 list_del_init(&evsel->node);
195 perf_evlist__add(evlist, evsel); 200 perf_evlist__add(evlist, evsel);
196 } 201 }
@@ -205,7 +210,7 @@ void __perf_evlist__set_leader(struct list_head *list)
205 210
206 leader->nr_members = evsel->idx - leader->idx + 1; 211 leader->nr_members = evsel->idx - leader->idx + 1;
207 212
208 __evlist__for_each(list, evsel) { 213 __evlist__for_each_entry(list, evsel) {
209 evsel->leader = leader; 214 evsel->leader = leader;
210 } 215 }
211} 216}
@@ -296,7 +301,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
296 return 0; 301 return 0;
297 302
298out_delete_partial_list: 303out_delete_partial_list:
299 __evlist__for_each_safe(&head, n, evsel) 304 __evlist__for_each_entry_safe(&head, n, evsel)
300 perf_evsel__delete(evsel); 305 perf_evsel__delete(evsel);
301 return -1; 306 return -1;
302} 307}
@@ -317,7 +322,7 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
317{ 322{
318 struct perf_evsel *evsel; 323 struct perf_evsel *evsel;
319 324
320 evlist__for_each(evlist, evsel) { 325 evlist__for_each_entry(evlist, evsel) {
321 if (evsel->attr.type == PERF_TYPE_TRACEPOINT && 326 if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
322 (int)evsel->attr.config == id) 327 (int)evsel->attr.config == id)
323 return evsel; 328 return evsel;
@@ -332,7 +337,7 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
332{ 337{
333 struct perf_evsel *evsel; 338 struct perf_evsel *evsel;
334 339
335 evlist__for_each(evlist, evsel) { 340 evlist__for_each_entry(evlist, evsel) {
336 if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) && 341 if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) &&
337 (strcmp(evsel->name, name) == 0)) 342 (strcmp(evsel->name, name) == 0))
338 return evsel; 343 return evsel;
@@ -367,7 +372,7 @@ void perf_evlist__disable(struct perf_evlist *evlist)
367{ 372{
368 struct perf_evsel *pos; 373 struct perf_evsel *pos;
369 374
370 evlist__for_each(evlist, pos) { 375 evlist__for_each_entry(evlist, pos) {
371 if (!perf_evsel__is_group_leader(pos) || !pos->fd) 376 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
372 continue; 377 continue;
373 perf_evsel__disable(pos); 378 perf_evsel__disable(pos);
@@ -380,7 +385,7 @@ void perf_evlist__enable(struct perf_evlist *evlist)
380{ 385{
381 struct perf_evsel *pos; 386 struct perf_evsel *pos;
382 387
383 evlist__for_each(evlist, pos) { 388 evlist__for_each_entry(evlist, pos) {
384 if (!perf_evsel__is_group_leader(pos) || !pos->fd) 389 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
385 continue; 390 continue;
386 perf_evsel__enable(pos); 391 perf_evsel__enable(pos);
@@ -448,7 +453,7 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
448 int nfds = 0; 453 int nfds = 0;
449 struct perf_evsel *evsel; 454 struct perf_evsel *evsel;
450 455
451 evlist__for_each(evlist, evsel) { 456 evlist__for_each_entry(evlist, evsel) {
452 if (evsel->system_wide) 457 if (evsel->system_wide)
453 nfds += nr_cpus; 458 nfds += nr_cpus;
454 else 459 else
@@ -462,15 +467,16 @@ int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
462 return 0; 467 return 0;
463} 468}
464 469
465static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx) 470static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd,
471 struct perf_mmap *map, short revent)
466{ 472{
467 int pos = fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP); 473 int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP);
468 /* 474 /*
469 * Save the idx so that when we filter out fds POLLHUP'ed we can 475 * Save the idx so that when we filter out fds POLLHUP'ed we can
470 * close the associated evlist->mmap[] entry. 476 * close the associated evlist->mmap[] entry.
471 */ 477 */
472 if (pos >= 0) { 478 if (pos >= 0) {
473 evlist->pollfd.priv[pos].idx = idx; 479 evlist->pollfd.priv[pos].ptr = map;
474 480
475 fcntl(fd, F_SETFL, O_NONBLOCK); 481 fcntl(fd, F_SETFL, O_NONBLOCK);
476 } 482 }
@@ -480,20 +486,22 @@ static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx
480 486
481int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) 487int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
482{ 488{
483 return __perf_evlist__add_pollfd(evlist, fd, -1); 489 return __perf_evlist__add_pollfd(evlist, fd, NULL, POLLIN);
484} 490}
485 491
486static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd) 492static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd,
493 void *arg __maybe_unused)
487{ 494{
488 struct perf_evlist *evlist = container_of(fda, struct perf_evlist, pollfd); 495 struct perf_mmap *map = fda->priv[fd].ptr;
489 496
490 perf_evlist__mmap_put(evlist, fda->priv[fd].idx); 497 if (map)
498 perf_mmap__put(map);
491} 499}
492 500
493int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) 501int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask)
494{ 502{
495 return fdarray__filter(&evlist->pollfd, revents_and_mask, 503 return fdarray__filter(&evlist->pollfd, revents_and_mask,
496 perf_evlist__munmap_filtered); 504 perf_evlist__munmap_filtered, NULL);
497} 505}
498 506
499int perf_evlist__poll(struct perf_evlist *evlist, int timeout) 507int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
@@ -647,8 +655,8 @@ static int perf_evlist__event2id(struct perf_evlist *evlist,
647 return 0; 655 return 0;
648} 656}
649 657
650static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, 658struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
651 union perf_event *event) 659 union perf_event *event)
652{ 660{
653 struct perf_evsel *first = perf_evlist__first(evlist); 661 struct perf_evsel *first = perf_evlist__first(evlist);
654 struct hlist_head *head; 662 struct hlist_head *head;
@@ -684,8 +692,11 @@ static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value)
684{ 692{
685 int i; 693 int i;
686 694
695 if (!evlist->backward_mmap)
696 return 0;
697
687 for (i = 0; i < evlist->nr_mmaps; i++) { 698 for (i = 0; i < evlist->nr_mmaps; i++) {
688 int fd = evlist->mmap[i].fd; 699 int fd = evlist->backward_mmap[i].fd;
689 int err; 700 int err;
690 701
691 if (fd < 0) 702 if (fd < 0)
@@ -697,12 +708,12 @@ static int perf_evlist__set_paused(struct perf_evlist *evlist, bool value)
697 return 0; 708 return 0;
698} 709}
699 710
700int perf_evlist__pause(struct perf_evlist *evlist) 711static int perf_evlist__pause(struct perf_evlist *evlist)
701{ 712{
702 return perf_evlist__set_paused(evlist, true); 713 return perf_evlist__set_paused(evlist, true);
703} 714}
704 715
705int perf_evlist__resume(struct perf_evlist *evlist) 716static int perf_evlist__resume(struct perf_evlist *evlist)
706{ 717{
707 return perf_evlist__set_paused(evlist, false); 718 return perf_evlist__set_paused(evlist, false);
708} 719}
@@ -777,9 +788,8 @@ broken_event:
777 return event; 788 return event;
778} 789}
779 790
780union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) 791union perf_event *perf_mmap__read_forward(struct perf_mmap *md, bool check_messup)
781{ 792{
782 struct perf_mmap *md = &evlist->mmap[idx];
783 u64 head; 793 u64 head;
784 u64 old = md->prev; 794 u64 old = md->prev;
785 795
@@ -791,13 +801,12 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
791 801
792 head = perf_mmap__read_head(md); 802 head = perf_mmap__read_head(md);
793 803
794 return perf_mmap__read(md, evlist->overwrite, old, head, &md->prev); 804 return perf_mmap__read(md, check_messup, old, head, &md->prev);
795} 805}
796 806
797union perf_event * 807union perf_event *
798perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx) 808perf_mmap__read_backward(struct perf_mmap *md)
799{ 809{
800 struct perf_mmap *md = &evlist->mmap[idx];
801 u64 head, end; 810 u64 head, end;
802 u64 start = md->prev; 811 u64 start = md->prev;
803 812
@@ -832,9 +841,38 @@ perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
832 return perf_mmap__read(md, false, start, end, &md->prev); 841 return perf_mmap__read(md, false, start, end, &md->prev);
833} 842}
834 843
835void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx) 844union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int idx)
845{
846 struct perf_mmap *md = &evlist->mmap[idx];
847
848 /*
849 * Check messup is required for forward overwritable ring buffer:
850 * memory pointed by md->prev can be overwritten in this case.
851 * No need for read-write ring buffer: kernel stop outputting when
852 * it hit md->prev (perf_mmap__consume()).
853 */
854 return perf_mmap__read_forward(md, evlist->overwrite);
855}
856
857union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
836{ 858{
837 struct perf_mmap *md = &evlist->mmap[idx]; 859 struct perf_mmap *md = &evlist->mmap[idx];
860
861 /*
862 * No need to check messup for backward ring buffer:
863 * We can always read arbitrary long data from a backward
864 * ring buffer unless we forget to pause it before reading.
865 */
866 return perf_mmap__read_backward(md);
867}
868
869union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
870{
871 return perf_evlist__mmap_read_forward(evlist, idx);
872}
873
874void perf_mmap__read_catchup(struct perf_mmap *md)
875{
838 u64 head; 876 u64 head;
839 877
840 if (!atomic_read(&md->refcnt)) 878 if (!atomic_read(&md->refcnt))
@@ -844,36 +882,44 @@ void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
844 md->prev = head; 882 md->prev = head;
845} 883}
846 884
885void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
886{
887 perf_mmap__read_catchup(&evlist->mmap[idx]);
888}
889
847static bool perf_mmap__empty(struct perf_mmap *md) 890static bool perf_mmap__empty(struct perf_mmap *md)
848{ 891{
849 return perf_mmap__read_head(md) == md->prev && !md->auxtrace_mmap.base; 892 return perf_mmap__read_head(md) == md->prev && !md->auxtrace_mmap.base;
850} 893}
851 894
852static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx) 895static void perf_mmap__get(struct perf_mmap *map)
853{ 896{
854 atomic_inc(&evlist->mmap[idx].refcnt); 897 atomic_inc(&map->refcnt);
855} 898}
856 899
857static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx) 900static void perf_mmap__put(struct perf_mmap *md)
858{ 901{
859 BUG_ON(atomic_read(&evlist->mmap[idx].refcnt) == 0); 902 BUG_ON(md->base && atomic_read(&md->refcnt) == 0);
860 903
861 if (atomic_dec_and_test(&evlist->mmap[idx].refcnt)) 904 if (atomic_dec_and_test(&md->refcnt))
862 __perf_evlist__munmap(evlist, idx); 905 perf_mmap__munmap(md);
863} 906}
864 907
865void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) 908void perf_mmap__consume(struct perf_mmap *md, bool overwrite)
866{ 909{
867 struct perf_mmap *md = &evlist->mmap[idx]; 910 if (!overwrite) {
868
869 if (!evlist->overwrite) {
870 u64 old = md->prev; 911 u64 old = md->prev;
871 912
872 perf_mmap__write_tail(md, old); 913 perf_mmap__write_tail(md, old);
873 } 914 }
874 915
875 if (atomic_read(&md->refcnt) == 1 && perf_mmap__empty(md)) 916 if (atomic_read(&md->refcnt) == 1 && perf_mmap__empty(md))
876 perf_evlist__mmap_put(evlist, idx); 917 perf_mmap__put(md);
918}
919
920void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
921{
922 perf_mmap__consume(&evlist->mmap[idx], evlist->overwrite);
877} 923}
878 924
879int __weak auxtrace_mmap__mmap(struct auxtrace_mmap *mm __maybe_unused, 925int __weak auxtrace_mmap__mmap(struct auxtrace_mmap *mm __maybe_unused,
@@ -904,41 +950,52 @@ void __weak auxtrace_mmap_params__set_idx(
904{ 950{
905} 951}
906 952
907static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx) 953static void perf_mmap__munmap(struct perf_mmap *map)
908{ 954{
909 if (evlist->mmap[idx].base != NULL) { 955 if (map->base != NULL) {
910 munmap(evlist->mmap[idx].base, evlist->mmap_len); 956 munmap(map->base, perf_mmap__mmap_len(map));
911 evlist->mmap[idx].base = NULL; 957 map->base = NULL;
912 evlist->mmap[idx].fd = -1; 958 map->fd = -1;
913 atomic_set(&evlist->mmap[idx].refcnt, 0); 959 atomic_set(&map->refcnt, 0);
914 } 960 }
915 auxtrace_mmap__munmap(&evlist->mmap[idx].auxtrace_mmap); 961 auxtrace_mmap__munmap(&map->auxtrace_mmap);
916} 962}
917 963
918void perf_evlist__munmap(struct perf_evlist *evlist) 964static void perf_evlist__munmap_nofree(struct perf_evlist *evlist)
919{ 965{
920 int i; 966 int i;
921 967
922 if (evlist->mmap == NULL) 968 if (evlist->mmap)
923 return; 969 for (i = 0; i < evlist->nr_mmaps; i++)
970 perf_mmap__munmap(&evlist->mmap[i]);
924 971
925 for (i = 0; i < evlist->nr_mmaps; i++) 972 if (evlist->backward_mmap)
926 __perf_evlist__munmap(evlist, i); 973 for (i = 0; i < evlist->nr_mmaps; i++)
974 perf_mmap__munmap(&evlist->backward_mmap[i]);
975}
927 976
977void perf_evlist__munmap(struct perf_evlist *evlist)
978{
979 perf_evlist__munmap_nofree(evlist);
928 zfree(&evlist->mmap); 980 zfree(&evlist->mmap);
981 zfree(&evlist->backward_mmap);
929} 982}
930 983
931static int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 984static struct perf_mmap *perf_evlist__alloc_mmap(struct perf_evlist *evlist)
932{ 985{
933 int i; 986 int i;
987 struct perf_mmap *map;
934 988
935 evlist->nr_mmaps = cpu_map__nr(evlist->cpus); 989 evlist->nr_mmaps = cpu_map__nr(evlist->cpus);
936 if (cpu_map__empty(evlist->cpus)) 990 if (cpu_map__empty(evlist->cpus))
937 evlist->nr_mmaps = thread_map__nr(evlist->threads); 991 evlist->nr_mmaps = thread_map__nr(evlist->threads);
938 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); 992 map = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
993 if (!map)
994 return NULL;
995
939 for (i = 0; i < evlist->nr_mmaps; i++) 996 for (i = 0; i < evlist->nr_mmaps; i++)
940 evlist->mmap[i].fd = -1; 997 map[i].fd = -1;
941 return evlist->mmap != NULL ? 0 : -ENOMEM; 998 return map;
942} 999}
943 1000
944struct mmap_params { 1001struct mmap_params {
@@ -947,8 +1004,8 @@ struct mmap_params {
947 struct auxtrace_mmap_params auxtrace_mp; 1004 struct auxtrace_mmap_params auxtrace_mp;
948}; 1005};
949 1006
950static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx, 1007static int perf_mmap__mmap(struct perf_mmap *map,
951 struct mmap_params *mp, int fd) 1008 struct mmap_params *mp, int fd)
952{ 1009{
953 /* 1010 /*
954 * The last one will be done at perf_evlist__mmap_consume(), so that we 1011 * The last one will be done at perf_evlist__mmap_consume(), so that we
@@ -963,35 +1020,61 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
963 * evlist layer can't just drop it when filtering events in 1020 * evlist layer can't just drop it when filtering events in
964 * perf_evlist__filter_pollfd(). 1021 * perf_evlist__filter_pollfd().
965 */ 1022 */
966 atomic_set(&evlist->mmap[idx].refcnt, 2); 1023 atomic_set(&map->refcnt, 2);
967 evlist->mmap[idx].prev = 0; 1024 map->prev = 0;
968 evlist->mmap[idx].mask = mp->mask; 1025 map->mask = mp->mask;
969 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, mp->prot, 1026 map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot,
970 MAP_SHARED, fd, 0); 1027 MAP_SHARED, fd, 0);
971 if (evlist->mmap[idx].base == MAP_FAILED) { 1028 if (map->base == MAP_FAILED) {
972 pr_debug2("failed to mmap perf event ring buffer, error %d\n", 1029 pr_debug2("failed to mmap perf event ring buffer, error %d\n",
973 errno); 1030 errno);
974 evlist->mmap[idx].base = NULL; 1031 map->base = NULL;
975 return -1; 1032 return -1;
976 } 1033 }
977 evlist->mmap[idx].fd = fd; 1034 map->fd = fd;
978 1035
979 if (auxtrace_mmap__mmap(&evlist->mmap[idx].auxtrace_mmap, 1036 if (auxtrace_mmap__mmap(&map->auxtrace_mmap,
980 &mp->auxtrace_mp, evlist->mmap[idx].base, fd)) 1037 &mp->auxtrace_mp, map->base, fd))
981 return -1; 1038 return -1;
982 1039
983 return 0; 1040 return 0;
984} 1041}
985 1042
1043static bool
1044perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused,
1045 struct perf_evsel *evsel)
1046{
1047 if (evsel->attr.write_backward)
1048 return false;
1049 return true;
1050}
1051
986static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, 1052static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
987 struct mmap_params *mp, int cpu, 1053 struct mmap_params *mp, int cpu,
988 int thread, int *output) 1054 int thread, int *_output, int *_output_backward)
989{ 1055{
990 struct perf_evsel *evsel; 1056 struct perf_evsel *evsel;
1057 int revent;
991 1058
992 evlist__for_each(evlist, evsel) { 1059 evlist__for_each_entry(evlist, evsel) {
1060 struct perf_mmap *maps = evlist->mmap;
1061 int *output = _output;
993 int fd; 1062 int fd;
994 1063
1064 if (evsel->attr.write_backward) {
1065 output = _output_backward;
1066 maps = evlist->backward_mmap;
1067
1068 if (!maps) {
1069 maps = perf_evlist__alloc_mmap(evlist);
1070 if (!maps)
1071 return -1;
1072 evlist->backward_mmap = maps;
1073 if (evlist->bkw_mmap_state == BKW_MMAP_NOTREADY)
1074 perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING);
1075 }
1076 }
1077
995 if (evsel->system_wide && thread) 1078 if (evsel->system_wide && thread)
996 continue; 1079 continue;
997 1080
@@ -999,15 +1082,18 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
999 1082
1000 if (*output == -1) { 1083 if (*output == -1) {
1001 *output = fd; 1084 *output = fd;
1002 if (__perf_evlist__mmap(evlist, idx, mp, *output) < 0) 1085
1086 if (perf_mmap__mmap(&maps[idx], mp, *output) < 0)
1003 return -1; 1087 return -1;
1004 } else { 1088 } else {
1005 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0) 1089 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
1006 return -1; 1090 return -1;
1007 1091
1008 perf_evlist__mmap_get(evlist, idx); 1092 perf_mmap__get(&maps[idx]);
1009 } 1093 }
1010 1094
1095 revent = perf_evlist__should_poll(evlist, evsel) ? POLLIN : 0;
1096
1011 /* 1097 /*
1012 * The system_wide flag causes a selected event to be opened 1098 * The system_wide flag causes a selected event to be opened
1013 * always without a pid. Consequently it will never get a 1099 * always without a pid. Consequently it will never get a
@@ -1016,8 +1102,8 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
1016 * Therefore don't add it for polling. 1102 * Therefore don't add it for polling.
1017 */ 1103 */
1018 if (!evsel->system_wide && 1104 if (!evsel->system_wide &&
1019 __perf_evlist__add_pollfd(evlist, fd, idx) < 0) { 1105 __perf_evlist__add_pollfd(evlist, fd, &maps[idx], revent) < 0) {
1020 perf_evlist__mmap_put(evlist, idx); 1106 perf_mmap__put(&maps[idx]);
1021 return -1; 1107 return -1;
1022 } 1108 }
1023 1109
@@ -1043,13 +1129,14 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist,
1043 pr_debug2("perf event ring buffer mmapped per cpu\n"); 1129 pr_debug2("perf event ring buffer mmapped per cpu\n");
1044 for (cpu = 0; cpu < nr_cpus; cpu++) { 1130 for (cpu = 0; cpu < nr_cpus; cpu++) {
1045 int output = -1; 1131 int output = -1;
1132 int output_backward = -1;
1046 1133
1047 auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, cpu, 1134 auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, cpu,
1048 true); 1135 true);
1049 1136
1050 for (thread = 0; thread < nr_threads; thread++) { 1137 for (thread = 0; thread < nr_threads; thread++) {
1051 if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu, 1138 if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu,
1052 thread, &output)) 1139 thread, &output, &output_backward))
1053 goto out_unmap; 1140 goto out_unmap;
1054 } 1141 }
1055 } 1142 }
@@ -1057,8 +1144,7 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist,
1057 return 0; 1144 return 0;
1058 1145
1059out_unmap: 1146out_unmap:
1060 for (cpu = 0; cpu < nr_cpus; cpu++) 1147 perf_evlist__munmap_nofree(evlist);
1061 __perf_evlist__munmap(evlist, cpu);
1062 return -1; 1148 return -1;
1063} 1149}
1064 1150
@@ -1071,20 +1157,20 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist,
1071 pr_debug2("perf event ring buffer mmapped per thread\n"); 1157 pr_debug2("perf event ring buffer mmapped per thread\n");
1072 for (thread = 0; thread < nr_threads; thread++) { 1158 for (thread = 0; thread < nr_threads; thread++) {
1073 int output = -1; 1159 int output = -1;
1160 int output_backward = -1;
1074 1161
1075 auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, thread, 1162 auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, thread,
1076 false); 1163 false);
1077 1164
1078 if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread, 1165 if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread,
1079 &output)) 1166 &output, &output_backward))
1080 goto out_unmap; 1167 goto out_unmap;
1081 } 1168 }
1082 1169
1083 return 0; 1170 return 0;
1084 1171
1085out_unmap: 1172out_unmap:
1086 for (thread = 0; thread < nr_threads; thread++) 1173 perf_evlist__munmap_nofree(evlist);
1087 __perf_evlist__munmap(evlist, thread);
1088 return -1; 1174 return -1;
1089} 1175}
1090 1176
@@ -1217,7 +1303,9 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
1217 .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), 1303 .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE),
1218 }; 1304 };
1219 1305
1220 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 1306 if (!evlist->mmap)
1307 evlist->mmap = perf_evlist__alloc_mmap(evlist);
1308 if (!evlist->mmap)
1221 return -ENOMEM; 1309 return -ENOMEM;
1222 1310
1223 if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) 1311 if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
@@ -1231,7 +1319,7 @@ int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
1231 auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->mmap_len, 1319 auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->mmap_len,
1232 auxtrace_pages, auxtrace_overwrite); 1320 auxtrace_pages, auxtrace_overwrite);
1233 1321
1234 evlist__for_each(evlist, evsel) { 1322 evlist__for_each_entry(evlist, evsel) {
1235 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 1323 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
1236 evsel->sample_id == NULL && 1324 evsel->sample_id == NULL &&
1237 perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0) 1325 perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
@@ -1307,7 +1395,7 @@ void __perf_evlist__set_sample_bit(struct perf_evlist *evlist,
1307{ 1395{
1308 struct perf_evsel *evsel; 1396 struct perf_evsel *evsel;
1309 1397
1310 evlist__for_each(evlist, evsel) 1398 evlist__for_each_entry(evlist, evsel)
1311 __perf_evsel__set_sample_bit(evsel, bit); 1399 __perf_evsel__set_sample_bit(evsel, bit);
1312} 1400}
1313 1401
@@ -1316,7 +1404,7 @@ void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist,
1316{ 1404{
1317 struct perf_evsel *evsel; 1405 struct perf_evsel *evsel;
1318 1406
1319 evlist__for_each(evlist, evsel) 1407 evlist__for_each_entry(evlist, evsel)
1320 __perf_evsel__reset_sample_bit(evsel, bit); 1408 __perf_evsel__reset_sample_bit(evsel, bit);
1321} 1409}
1322 1410
@@ -1327,7 +1415,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e
1327 const int ncpus = cpu_map__nr(evlist->cpus), 1415 const int ncpus = cpu_map__nr(evlist->cpus),
1328 nthreads = thread_map__nr(evlist->threads); 1416 nthreads = thread_map__nr(evlist->threads);
1329 1417
1330 evlist__for_each(evlist, evsel) { 1418 evlist__for_each_entry(evlist, evsel) {
1331 if (evsel->filter == NULL) 1419 if (evsel->filter == NULL)
1332 continue; 1420 continue;
1333 1421
@@ -1350,7 +1438,7 @@ int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
1350 struct perf_evsel *evsel; 1438 struct perf_evsel *evsel;
1351 int err = 0; 1439 int err = 0;
1352 1440
1353 evlist__for_each(evlist, evsel) { 1441 evlist__for_each_entry(evlist, evsel) {
1354 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) 1442 if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
1355 continue; 1443 continue;
1356 1444
@@ -1404,7 +1492,7 @@ bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
1404 if (evlist->id_pos < 0 || evlist->is_pos < 0) 1492 if (evlist->id_pos < 0 || evlist->is_pos < 0)
1405 return false; 1493 return false;
1406 1494
1407 evlist__for_each(evlist, pos) { 1495 evlist__for_each_entry(evlist, pos) {
1408 if (pos->id_pos != evlist->id_pos || 1496 if (pos->id_pos != evlist->id_pos ||
1409 pos->is_pos != evlist->is_pos) 1497 pos->is_pos != evlist->is_pos)
1410 return false; 1498 return false;
@@ -1420,7 +1508,7 @@ u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
1420 if (evlist->combined_sample_type) 1508 if (evlist->combined_sample_type)
1421 return evlist->combined_sample_type; 1509 return evlist->combined_sample_type;
1422 1510
1423 evlist__for_each(evlist, evsel) 1511 evlist__for_each_entry(evlist, evsel)
1424 evlist->combined_sample_type |= evsel->attr.sample_type; 1512 evlist->combined_sample_type |= evsel->attr.sample_type;
1425 1513
1426 return evlist->combined_sample_type; 1514 return evlist->combined_sample_type;
@@ -1437,7 +1525,7 @@ u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist)
1437 struct perf_evsel *evsel; 1525 struct perf_evsel *evsel;
1438 u64 branch_type = 0; 1526 u64 branch_type = 0;
1439 1527
1440 evlist__for_each(evlist, evsel) 1528 evlist__for_each_entry(evlist, evsel)
1441 branch_type |= evsel->attr.branch_sample_type; 1529 branch_type |= evsel->attr.branch_sample_type;
1442 return branch_type; 1530 return branch_type;
1443} 1531}
@@ -1448,7 +1536,7 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
1448 u64 read_format = first->attr.read_format; 1536 u64 read_format = first->attr.read_format;
1449 u64 sample_type = first->attr.sample_type; 1537 u64 sample_type = first->attr.sample_type;
1450 1538
1451 evlist__for_each(evlist, pos) { 1539 evlist__for_each_entry(evlist, pos) {
1452 if (read_format != pos->attr.read_format) 1540 if (read_format != pos->attr.read_format)
1453 return false; 1541 return false;
1454 } 1542 }
@@ -1505,7 +1593,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
1505{ 1593{
1506 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first; 1594 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
1507 1595
1508 evlist__for_each_continue(evlist, pos) { 1596 evlist__for_each_entry_continue(evlist, pos) {
1509 if (first->attr.sample_id_all != pos->attr.sample_id_all) 1597 if (first->attr.sample_id_all != pos->attr.sample_id_all)
1510 return false; 1598 return false;
1511 } 1599 }
@@ -1532,7 +1620,7 @@ void perf_evlist__close(struct perf_evlist *evlist)
1532 int nthreads = thread_map__nr(evlist->threads); 1620 int nthreads = thread_map__nr(evlist->threads);
1533 int n; 1621 int n;
1534 1622
1535 evlist__for_each_reverse(evlist, evsel) { 1623 evlist__for_each_entry_reverse(evlist, evsel) {
1536 n = evsel->cpus ? evsel->cpus->nr : ncpus; 1624 n = evsel->cpus ? evsel->cpus->nr : ncpus;
1537 perf_evsel__close(evsel, n, nthreads); 1625 perf_evsel__close(evsel, n, nthreads);
1538 } 1626 }
@@ -1586,7 +1674,7 @@ int perf_evlist__open(struct perf_evlist *evlist)
1586 1674
1587 perf_evlist__update_id_pos(evlist); 1675 perf_evlist__update_id_pos(evlist);
1588 1676
1589 evlist__for_each(evlist, evsel) { 1677 evlist__for_each_entry(evlist, evsel) {
1590 err = perf_evsel__open(evsel, evsel->cpus, evsel->threads); 1678 err = perf_evsel__open(evsel, evsel->cpus, evsel->threads);
1591 if (err < 0) 1679 if (err < 0)
1592 goto out_err; 1680 goto out_err;
@@ -1747,7 +1835,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
1747 struct perf_evsel *evsel; 1835 struct perf_evsel *evsel;
1748 size_t printed = 0; 1836 size_t printed = 0;
1749 1837
1750 evlist__for_each(evlist, evsel) { 1838 evlist__for_each_entry(evlist, evsel) {
1751 printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "", 1839 printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
1752 perf_evsel__name(evsel)); 1840 perf_evsel__name(evsel));
1753 } 1841 }
@@ -1759,7 +1847,7 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist,
1759 int err, char *buf, size_t size) 1847 int err, char *buf, size_t size)
1760{ 1848{
1761 int printed, value; 1849 int printed, value;
1762 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); 1850 char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf));
1763 1851
1764 switch (err) { 1852 switch (err) {
1765 case EACCES: 1853 case EACCES:
@@ -1811,7 +1899,7 @@ out_default:
1811 1899
1812int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) 1900int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
1813{ 1901{
1814 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); 1902 char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf));
1815 int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; 1903 int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0;
1816 1904
1817 switch (err) { 1905 switch (err) {
@@ -1849,7 +1937,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
1849 if (move_evsel == perf_evlist__first(evlist)) 1937 if (move_evsel == perf_evlist__first(evlist))
1850 return; 1938 return;
1851 1939
1852 evlist__for_each_safe(evlist, n, evsel) { 1940 evlist__for_each_entry_safe(evlist, n, evsel) {
1853 if (evsel->leader == move_evsel->leader) 1941 if (evsel->leader == move_evsel->leader)
1854 list_move_tail(&evsel->node, &move); 1942 list_move_tail(&evsel->node, &move);
1855 } 1943 }
@@ -1865,7 +1953,7 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
1865 if (tracking_evsel->tracking) 1953 if (tracking_evsel->tracking)
1866 return; 1954 return;
1867 1955
1868 evlist__for_each(evlist, evsel) { 1956 evlist__for_each_entry(evlist, evsel) {
1869 if (evsel != tracking_evsel) 1957 if (evsel != tracking_evsel)
1870 evsel->tracking = false; 1958 evsel->tracking = false;
1871 } 1959 }
@@ -1879,7 +1967,7 @@ perf_evlist__find_evsel_by_str(struct perf_evlist *evlist,
1879{ 1967{
1880 struct perf_evsel *evsel; 1968 struct perf_evsel *evsel;
1881 1969
1882 evlist__for_each(evlist, evsel) { 1970 evlist__for_each_entry(evlist, evsel) {
1883 if (!evsel->name) 1971 if (!evsel->name)
1884 continue; 1972 continue;
1885 if (strcmp(str, evsel->name) == 0) 1973 if (strcmp(str, evsel->name) == 0)
@@ -1888,3 +1976,61 @@ perf_evlist__find_evsel_by_str(struct perf_evlist *evlist,
1888 1976
1889 return NULL; 1977 return NULL;
1890} 1978}
1979
1980void perf_evlist__toggle_bkw_mmap(struct perf_evlist *evlist,
1981 enum bkw_mmap_state state)
1982{
1983 enum bkw_mmap_state old_state = evlist->bkw_mmap_state;
1984 enum action {
1985 NONE,
1986 PAUSE,
1987 RESUME,
1988 } action = NONE;
1989
1990 if (!evlist->backward_mmap)
1991 return;
1992
1993 switch (old_state) {
1994 case BKW_MMAP_NOTREADY: {
1995 if (state != BKW_MMAP_RUNNING)
1996 goto state_err;;
1997 break;
1998 }
1999 case BKW_MMAP_RUNNING: {
2000 if (state != BKW_MMAP_DATA_PENDING)
2001 goto state_err;
2002 action = PAUSE;
2003 break;
2004 }
2005 case BKW_MMAP_DATA_PENDING: {
2006 if (state != BKW_MMAP_EMPTY)
2007 goto state_err;
2008 break;
2009 }
2010 case BKW_MMAP_EMPTY: {
2011 if (state != BKW_MMAP_RUNNING)
2012 goto state_err;
2013 action = RESUME;
2014 break;
2015 }
2016 default:
2017 WARN_ONCE(1, "Shouldn't get there\n");
2018 }
2019
2020 evlist->bkw_mmap_state = state;
2021
2022 switch (action) {
2023 case PAUSE:
2024 perf_evlist__pause(evlist);
2025 break;
2026 case RESUME:
2027 perf_evlist__resume(evlist);
2028 break;
2029 case NONE:
2030 default:
2031 break;
2032 }
2033
2034state_err:
2035 return;
2036}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index d740fb877ab6..4fd034f22d2f 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -35,6 +35,40 @@ struct perf_mmap {
35 char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8))); 35 char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8)));
36}; 36};
37 37
38static inline size_t
39perf_mmap__mmap_len(struct perf_mmap *map)
40{
41 return map->mask + 1 + page_size;
42}
43
44/*
45 * State machine of bkw_mmap_state:
46 *
47 * .________________(forbid)_____________.
48 * | V
49 * NOTREADY --(0)--> RUNNING --(1)--> DATA_PENDING --(2)--> EMPTY
50 * ^ ^ | ^ |
51 * | |__(forbid)____/ |___(forbid)___/|
52 * | |
53 * \_________________(3)_______________/
54 *
55 * NOTREADY : Backward ring buffers are not ready
56 * RUNNING : Backward ring buffers are recording
57 * DATA_PENDING : We are required to collect data from backward ring buffers
58 * EMPTY : We have collected data from backward ring buffers.
59 *
60 * (0): Setup backward ring buffer
61 * (1): Pause ring buffers for reading
62 * (2): Read from ring buffers
63 * (3): Resume ring buffers for recording
64 */
65enum bkw_mmap_state {
66 BKW_MMAP_NOTREADY,
67 BKW_MMAP_RUNNING,
68 BKW_MMAP_DATA_PENDING,
69 BKW_MMAP_EMPTY,
70};
71
38struct perf_evlist { 72struct perf_evlist {
39 struct list_head entries; 73 struct list_head entries;
40 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; 74 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
@@ -44,17 +78,18 @@ struct perf_evlist {
44 bool overwrite; 78 bool overwrite;
45 bool enabled; 79 bool enabled;
46 bool has_user_cpus; 80 bool has_user_cpus;
47 bool backward;
48 size_t mmap_len; 81 size_t mmap_len;
49 int id_pos; 82 int id_pos;
50 int is_pos; 83 int is_pos;
51 u64 combined_sample_type; 84 u64 combined_sample_type;
85 enum bkw_mmap_state bkw_mmap_state;
52 struct { 86 struct {
53 int cork_fd; 87 int cork_fd;
54 pid_t pid; 88 pid_t pid;
55 } workload; 89 } workload;
56 struct fdarray pollfd; 90 struct fdarray pollfd;
57 struct perf_mmap *mmap; 91 struct perf_mmap *mmap;
92 struct perf_mmap *backward_mmap;
58 struct thread_map *threads; 93 struct thread_map *threads;
59 struct cpu_map *cpus; 94 struct cpu_map *cpus;
60 struct perf_evsel *selected; 95 struct perf_evsel *selected;
@@ -129,16 +164,24 @@ struct perf_evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist,
129 164
130struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id); 165struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
131 166
167void perf_evlist__toggle_bkw_mmap(struct perf_evlist *evlist, enum bkw_mmap_state state);
168
169union perf_event *perf_mmap__read_forward(struct perf_mmap *map, bool check_messup);
170union perf_event *perf_mmap__read_backward(struct perf_mmap *map);
171
172void perf_mmap__read_catchup(struct perf_mmap *md);
173void perf_mmap__consume(struct perf_mmap *md, bool overwrite);
174
132union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx); 175union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx);
133 176
177union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist,
178 int idx);
134union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, 179union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist,
135 int idx); 180 int idx);
136void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx); 181void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx);
137 182
138void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx); 183void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
139 184
140int perf_evlist__pause(struct perf_evlist *evlist);
141int perf_evlist__resume(struct perf_evlist *evlist);
142int perf_evlist__open(struct perf_evlist *evlist); 185int perf_evlist__open(struct perf_evlist *evlist);
143void perf_evlist__close(struct perf_evlist *evlist); 186void perf_evlist__close(struct perf_evlist *evlist);
144 187
@@ -249,70 +292,70 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
249 struct perf_evsel *move_evsel); 292 struct perf_evsel *move_evsel);
250 293
251/** 294/**
252 * __evlist__for_each - iterate thru all the evsels 295 * __evlist__for_each_entry - iterate thru all the evsels
253 * @list: list_head instance to iterate 296 * @list: list_head instance to iterate
254 * @evsel: struct evsel iterator 297 * @evsel: struct evsel iterator
255 */ 298 */
256#define __evlist__for_each(list, evsel) \ 299#define __evlist__for_each_entry(list, evsel) \
257 list_for_each_entry(evsel, list, node) 300 list_for_each_entry(evsel, list, node)
258 301
259/** 302/**
260 * evlist__for_each - iterate thru all the evsels 303 * evlist__for_each_entry - iterate thru all the evsels
261 * @evlist: evlist instance to iterate 304 * @evlist: evlist instance to iterate
262 * @evsel: struct evsel iterator 305 * @evsel: struct evsel iterator
263 */ 306 */
264#define evlist__for_each(evlist, evsel) \ 307#define evlist__for_each_entry(evlist, evsel) \
265 __evlist__for_each(&(evlist)->entries, evsel) 308 __evlist__for_each_entry(&(evlist)->entries, evsel)
266 309
267/** 310/**
268 * __evlist__for_each_continue - continue iteration thru all the evsels 311 * __evlist__for_each_entry_continue - continue iteration thru all the evsels
269 * @list: list_head instance to iterate 312 * @list: list_head instance to iterate
270 * @evsel: struct evsel iterator 313 * @evsel: struct evsel iterator
271 */ 314 */
272#define __evlist__for_each_continue(list, evsel) \ 315#define __evlist__for_each_entry_continue(list, evsel) \
273 list_for_each_entry_continue(evsel, list, node) 316 list_for_each_entry_continue(evsel, list, node)
274 317
275/** 318/**
276 * evlist__for_each_continue - continue iteration thru all the evsels 319 * evlist__for_each_entry_continue - continue iteration thru all the evsels
277 * @evlist: evlist instance to iterate 320 * @evlist: evlist instance to iterate
278 * @evsel: struct evsel iterator 321 * @evsel: struct evsel iterator
279 */ 322 */
280#define evlist__for_each_continue(evlist, evsel) \ 323#define evlist__for_each_entry_continue(evlist, evsel) \
281 __evlist__for_each_continue(&(evlist)->entries, evsel) 324 __evlist__for_each_entry_continue(&(evlist)->entries, evsel)
282 325
283/** 326/**
284 * __evlist__for_each_reverse - iterate thru all the evsels in reverse order 327 * __evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order
285 * @list: list_head instance to iterate 328 * @list: list_head instance to iterate
286 * @evsel: struct evsel iterator 329 * @evsel: struct evsel iterator
287 */ 330 */
288#define __evlist__for_each_reverse(list, evsel) \ 331#define __evlist__for_each_entry_reverse(list, evsel) \
289 list_for_each_entry_reverse(evsel, list, node) 332 list_for_each_entry_reverse(evsel, list, node)
290 333
291/** 334/**
292 * evlist__for_each_reverse - iterate thru all the evsels in reverse order 335 * evlist__for_each_entry_reverse - iterate thru all the evsels in reverse order
293 * @evlist: evlist instance to iterate 336 * @evlist: evlist instance to iterate
294 * @evsel: struct evsel iterator 337 * @evsel: struct evsel iterator
295 */ 338 */
296#define evlist__for_each_reverse(evlist, evsel) \ 339#define evlist__for_each_entry_reverse(evlist, evsel) \
297 __evlist__for_each_reverse(&(evlist)->entries, evsel) 340 __evlist__for_each_entry_reverse(&(evlist)->entries, evsel)
298 341
299/** 342/**
300 * __evlist__for_each_safe - safely iterate thru all the evsels 343 * __evlist__for_each_entry_safe - safely iterate thru all the evsels
301 * @list: list_head instance to iterate 344 * @list: list_head instance to iterate
302 * @tmp: struct evsel temp iterator 345 * @tmp: struct evsel temp iterator
303 * @evsel: struct evsel iterator 346 * @evsel: struct evsel iterator
304 */ 347 */
305#define __evlist__for_each_safe(list, tmp, evsel) \ 348#define __evlist__for_each_entry_safe(list, tmp, evsel) \
306 list_for_each_entry_safe(evsel, tmp, list, node) 349 list_for_each_entry_safe(evsel, tmp, list, node)
307 350
308/** 351/**
309 * evlist__for_each_safe - safely iterate thru all the evsels 352 * evlist__for_each_entry_safe - safely iterate thru all the evsels
310 * @evlist: evlist instance to iterate 353 * @evlist: evlist instance to iterate
311 * @evsel: struct evsel iterator 354 * @evsel: struct evsel iterator
312 * @tmp: struct evsel temp iterator 355 * @tmp: struct evsel temp iterator
313 */ 356 */
314#define evlist__for_each_safe(evlist, tmp, evsel) \ 357#define evlist__for_each_entry_safe(evlist, tmp, evsel) \
315 __evlist__for_each_safe(&(evlist)->entries, tmp, evsel) 358 __evlist__for_each_entry_safe(&(evlist)->entries, tmp, evsel)
316 359
317void perf_evlist__set_tracking_event(struct perf_evlist *evlist, 360void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
318 struct perf_evsel *tracking_evsel); 361 struct perf_evsel *tracking_evsel);
@@ -321,4 +364,7 @@ void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr);
321 364
322struct perf_evsel * 365struct perf_evsel *
323perf_evlist__find_evsel_by_str(struct perf_evlist *evlist, const char *str); 366perf_evlist__find_evsel_by_str(struct perf_evlist *evlist, const char *str);
367
368struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
369 union perf_event *event);
324#endif /* __PERF_EVLIST_H */ 370#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 5d7037ef7d3b..8c54df61fe64 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -200,6 +200,24 @@ void perf_evsel__set_sample_id(struct perf_evsel *evsel,
200 evsel->attr.read_format |= PERF_FORMAT_ID; 200 evsel->attr.read_format |= PERF_FORMAT_ID;
201} 201}
202 202
203/**
204 * perf_evsel__is_function_event - Return whether given evsel is a function
205 * trace event
206 *
207 * @evsel - evsel selector to be tested
208 *
209 * Return %true if event is function trace event
210 */
211bool perf_evsel__is_function_event(struct perf_evsel *evsel)
212{
213#define FUNCTION_EVENT "ftrace:function"
214
215 return evsel->name &&
216 !strncmp(FUNCTION_EVENT, evsel->name, sizeof(FUNCTION_EVENT));
217
218#undef FUNCTION_EVENT
219}
220
203void perf_evsel__init(struct perf_evsel *evsel, 221void perf_evsel__init(struct perf_evsel *evsel,
204 struct perf_event_attr *attr, int idx) 222 struct perf_event_attr *attr, int idx)
205{ 223{
@@ -572,6 +590,8 @@ void perf_evsel__config_callchain(struct perf_evsel *evsel,
572 590
573 perf_evsel__set_sample_bit(evsel, CALLCHAIN); 591 perf_evsel__set_sample_bit(evsel, CALLCHAIN);
574 592
593 attr->sample_max_stack = param->max_stack;
594
575 if (param->record_mode == CALLCHAIN_LBR) { 595 if (param->record_mode == CALLCHAIN_LBR) {
576 if (!opts->branch_stack) { 596 if (!opts->branch_stack) {
577 if (attr->exclude_user) { 597 if (attr->exclude_user) {
@@ -635,7 +655,8 @@ static void apply_config_terms(struct perf_evsel *evsel,
635 struct perf_event_attr *attr = &evsel->attr; 655 struct perf_event_attr *attr = &evsel->attr;
636 struct callchain_param param; 656 struct callchain_param param;
637 u32 dump_size = 0; 657 u32 dump_size = 0;
638 char *callgraph_buf = NULL; 658 int max_stack = 0;
659 const char *callgraph_buf = NULL;
639 660
640 /* callgraph default */ 661 /* callgraph default */
641 param.record_mode = callchain_param.record_mode; 662 param.record_mode = callchain_param.record_mode;
@@ -662,6 +683,9 @@ static void apply_config_terms(struct perf_evsel *evsel,
662 case PERF_EVSEL__CONFIG_TERM_STACK_USER: 683 case PERF_EVSEL__CONFIG_TERM_STACK_USER:
663 dump_size = term->val.stack_user; 684 dump_size = term->val.stack_user;
664 break; 685 break;
686 case PERF_EVSEL__CONFIG_TERM_MAX_STACK:
687 max_stack = term->val.max_stack;
688 break;
665 case PERF_EVSEL__CONFIG_TERM_INHERIT: 689 case PERF_EVSEL__CONFIG_TERM_INHERIT:
666 /* 690 /*
667 * attr->inherit should has already been set by 691 * attr->inherit should has already been set by
@@ -671,13 +695,21 @@ static void apply_config_terms(struct perf_evsel *evsel,
671 */ 695 */
672 attr->inherit = term->val.inherit ? 1 : 0; 696 attr->inherit = term->val.inherit ? 1 : 0;
673 break; 697 break;
698 case PERF_EVSEL__CONFIG_TERM_OVERWRITE:
699 attr->write_backward = term->val.overwrite ? 1 : 0;
700 break;
674 default: 701 default:
675 break; 702 break;
676 } 703 }
677 } 704 }
678 705
679 /* User explicitly set per-event callgraph, clear the old setting and reset. */ 706 /* User explicitly set per-event callgraph, clear the old setting and reset. */
680 if ((callgraph_buf != NULL) || (dump_size > 0)) { 707 if ((callgraph_buf != NULL) || (dump_size > 0) || max_stack) {
708 if (max_stack) {
709 param.max_stack = max_stack;
710 if (callgraph_buf == NULL)
711 callgraph_buf = "fp";
712 }
681 713
682 /* parse callgraph parameters */ 714 /* parse callgraph parameters */
683 if (callgraph_buf != NULL) { 715 if (callgraph_buf != NULL) {
@@ -747,6 +779,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
747 779
748 attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1; 780 attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
749 attr->inherit = !opts->no_inherit; 781 attr->inherit = !opts->no_inherit;
782 attr->write_backward = opts->overwrite ? 1 : 0;
750 783
751 perf_evsel__set_sample_bit(evsel, IP); 784 perf_evsel__set_sample_bit(evsel, IP);
752 perf_evsel__set_sample_bit(evsel, TID); 785 perf_evsel__set_sample_bit(evsel, TID);
@@ -1329,6 +1362,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
1329 PRINT_ATTRf(clockid, p_signed); 1362 PRINT_ATTRf(clockid, p_signed);
1330 PRINT_ATTRf(sample_regs_intr, p_hex); 1363 PRINT_ATTRf(sample_regs_intr, p_hex);
1331 PRINT_ATTRf(aux_watermark, p_unsigned); 1364 PRINT_ATTRf(aux_watermark, p_unsigned);
1365 PRINT_ATTRf(sample_max_stack, p_unsigned);
1332 1366
1333 return ret; 1367 return ret;
1334} 1368}
@@ -1347,6 +1381,9 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
1347 int pid = -1, err; 1381 int pid = -1, err;
1348 enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE; 1382 enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE;
1349 1383
1384 if (perf_missing_features.write_backward && evsel->attr.write_backward)
1385 return -EINVAL;
1386
1350 if (evsel->system_wide) 1387 if (evsel->system_wide)
1351 nthreads = 1; 1388 nthreads = 1;
1352 else 1389 else
@@ -1377,8 +1414,6 @@ fallback_missing_features:
1377 if (perf_missing_features.lbr_flags) 1414 if (perf_missing_features.lbr_flags)
1378 evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | 1415 evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS |
1379 PERF_SAMPLE_BRANCH_NO_CYCLES); 1416 PERF_SAMPLE_BRANCH_NO_CYCLES);
1380 if (perf_missing_features.write_backward)
1381 evsel->attr.write_backward = false;
1382retry_sample_id: 1417retry_sample_id:
1383 if (perf_missing_features.sample_id_all) 1418 if (perf_missing_features.sample_id_all)
1384 evsel->attr.sample_id_all = 0; 1419 evsel->attr.sample_id_all = 0;
@@ -1441,12 +1476,6 @@ retry_open:
1441 err = -EINVAL; 1476 err = -EINVAL;
1442 goto out_close; 1477 goto out_close;
1443 } 1478 }
1444
1445 if (evsel->overwrite &&
1446 perf_missing_features.write_backward) {
1447 err = -EINVAL;
1448 goto out_close;
1449 }
1450 } 1479 }
1451 } 1480 }
1452 1481
@@ -1484,7 +1513,10 @@ try_fallback:
1484 * Must probe features in the order they were added to the 1513 * Must probe features in the order they were added to the
1485 * perf_event_attr interface. 1514 * perf_event_attr interface.
1486 */ 1515 */
1487 if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) { 1516 if (!perf_missing_features.write_backward && evsel->attr.write_backward) {
1517 perf_missing_features.write_backward = true;
1518 goto out_close;
1519 } else if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) {
1488 perf_missing_features.clockid_wrong = true; 1520 perf_missing_features.clockid_wrong = true;
1489 goto fallback_missing_features; 1521 goto fallback_missing_features;
1490 } else if (!perf_missing_features.clockid && evsel->attr.use_clockid) { 1522 } else if (!perf_missing_features.clockid && evsel->attr.use_clockid) {
@@ -1509,12 +1541,7 @@ try_fallback:
1509 PERF_SAMPLE_BRANCH_NO_FLAGS))) { 1541 PERF_SAMPLE_BRANCH_NO_FLAGS))) {
1510 perf_missing_features.lbr_flags = true; 1542 perf_missing_features.lbr_flags = true;
1511 goto fallback_missing_features; 1543 goto fallback_missing_features;
1512 } else if (!perf_missing_features.write_backward &&
1513 evsel->attr.write_backward) {
1514 perf_missing_features.write_backward = true;
1515 goto fallback_missing_features;
1516 } 1544 }
1517
1518out_close: 1545out_close:
1519 do { 1546 do {
1520 while (--thread >= 0) { 1547 while (--thread >= 0) {
@@ -2239,17 +2266,11 @@ void *perf_evsel__rawptr(struct perf_evsel *evsel, struct perf_sample *sample,
2239 return sample->raw_data + offset; 2266 return sample->raw_data + offset;
2240} 2267}
2241 2268
2242u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, 2269u64 format_field__intval(struct format_field *field, struct perf_sample *sample,
2243 const char *name) 2270 bool needs_swap)
2244{ 2271{
2245 struct format_field *field = perf_evsel__field(evsel, name);
2246 void *ptr;
2247 u64 value; 2272 u64 value;
2248 2273 void *ptr = sample->raw_data + field->offset;
2249 if (!field)
2250 return 0;
2251
2252 ptr = sample->raw_data + field->offset;
2253 2274
2254 switch (field->size) { 2275 switch (field->size) {
2255 case 1: 2276 case 1:
@@ -2267,7 +2288,7 @@ u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
2267 return 0; 2288 return 0;
2268 } 2289 }
2269 2290
2270 if (!evsel->needs_swap) 2291 if (!needs_swap)
2271 return value; 2292 return value;
2272 2293
2273 switch (field->size) { 2294 switch (field->size) {
@@ -2284,6 +2305,17 @@ u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
2284 return 0; 2305 return 0;
2285} 2306}
2286 2307
2308u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
2309 const char *name)
2310{
2311 struct format_field *field = perf_evsel__field(evsel, name);
2312
2313 if (!field)
2314 return 0;
2315
2316 return field ? format_field__intval(field, sample, evsel->needs_swap) : 0;
2317}
2318
2287bool perf_evsel__fallback(struct perf_evsel *evsel, int err, 2319bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
2288 char *msg, size_t msgsize) 2320 char *msg, size_t msgsize)
2289{ 2321{
@@ -2372,6 +2404,9 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
2372 "No such device - did you specify an out-of-range profile CPU?"); 2404 "No such device - did you specify an out-of-range profile CPU?");
2373 break; 2405 break;
2374 case EOPNOTSUPP: 2406 case EOPNOTSUPP:
2407 if (evsel->attr.sample_period != 0)
2408 return scnprintf(msg, size, "%s",
2409 "PMU Hardware doesn't support sampling/overflow-interrupts.");
2375 if (evsel->attr.precise_ip) 2410 if (evsel->attr.precise_ip)
2376 return scnprintf(msg, size, "%s", 2411 return scnprintf(msg, size, "%s",
2377 "\'precise\' request may not be supported. Try removing 'p' modifier."); 2412 "\'precise\' request may not be supported. Try removing 'p' modifier.");
@@ -2389,6 +2424,8 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
2389 "We found oprofile daemon running, please stop it and try again."); 2424 "We found oprofile daemon running, please stop it and try again.");
2390 break; 2425 break;
2391 case EINVAL: 2426 case EINVAL:
2427 if (evsel->attr.write_backward && perf_missing_features.write_backward)
2428 return scnprintf(msg, size, "Reading from overwrite event is not supported by this kernel.");
2392 if (perf_missing_features.clockid) 2429 if (perf_missing_features.clockid)
2393 return scnprintf(msg, size, "clockid feature not supported."); 2430 return scnprintf(msg, size, "clockid feature not supported.");
2394 if (perf_missing_features.clockid_wrong) 2431 if (perf_missing_features.clockid_wrong)
@@ -2402,6 +2439,13 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
2402 "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n" 2439 "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n"
2403 "/bin/dmesg may provide additional information.\n" 2440 "/bin/dmesg may provide additional information.\n"
2404 "No CONFIG_PERF_EVENTS=y kernel support configured?", 2441 "No CONFIG_PERF_EVENTS=y kernel support configured?",
2405 err, strerror_r(err, sbuf, sizeof(sbuf)), 2442 err, str_error_r(err, sbuf, sizeof(sbuf)),
2406 perf_evsel__name(evsel)); 2443 perf_evsel__name(evsel));
2407} 2444}
2445
2446char *perf_evsel__env_arch(struct perf_evsel *evsel)
2447{
2448 if (evsel && evsel->evlist && evsel->evlist->env)
2449 return evsel->evlist->env->arch;
2450 return NULL;
2451}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index c1f10159804c..8a4a6c9f1480 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -44,6 +44,8 @@ enum {
44 PERF_EVSEL__CONFIG_TERM_CALLGRAPH, 44 PERF_EVSEL__CONFIG_TERM_CALLGRAPH,
45 PERF_EVSEL__CONFIG_TERM_STACK_USER, 45 PERF_EVSEL__CONFIG_TERM_STACK_USER,
46 PERF_EVSEL__CONFIG_TERM_INHERIT, 46 PERF_EVSEL__CONFIG_TERM_INHERIT,
47 PERF_EVSEL__CONFIG_TERM_MAX_STACK,
48 PERF_EVSEL__CONFIG_TERM_OVERWRITE,
47 PERF_EVSEL__CONFIG_TERM_MAX, 49 PERF_EVSEL__CONFIG_TERM_MAX,
48}; 50};
49 51
@@ -56,7 +58,9 @@ struct perf_evsel_config_term {
56 bool time; 58 bool time;
57 char *callgraph; 59 char *callgraph;
58 u64 stack_user; 60 u64 stack_user;
61 int max_stack;
59 bool inherit; 62 bool inherit;
63 bool overwrite;
60 } val; 64 } val;
61}; 65};
62 66
@@ -112,7 +116,6 @@ struct perf_evsel {
112 bool tracking; 116 bool tracking;
113 bool per_pkg; 117 bool per_pkg;
114 bool precise_max; 118 bool precise_max;
115 bool overwrite;
116 /* parse modifier helper */ 119 /* parse modifier helper */
117 int exclude_GH; 120 int exclude_GH;
118 int nr_members; 121 int nr_members;
@@ -259,6 +262,8 @@ static inline char *perf_evsel__strval(struct perf_evsel *evsel,
259 262
260struct format_field; 263struct format_field;
261 264
265u64 format_field__intval(struct format_field *field, struct perf_sample *sample, bool needs_swap);
266
262struct format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name); 267struct format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name);
263 268
264#define perf_evsel__match(evsel, t, c) \ 269#define perf_evsel__match(evsel, t, c) \
@@ -351,23 +356,7 @@ static inline bool perf_evsel__is_group_event(struct perf_evsel *evsel)
351 return perf_evsel__is_group_leader(evsel) && evsel->nr_members > 1; 356 return perf_evsel__is_group_leader(evsel) && evsel->nr_members > 1;
352} 357}
353 358
354/** 359bool perf_evsel__is_function_event(struct perf_evsel *evsel);
355 * perf_evsel__is_function_event - Return whether given evsel is a function
356 * trace event
357 *
358 * @evsel - evsel selector to be tested
359 *
360 * Return %true if event is function trace event
361 */
362static inline bool perf_evsel__is_function_event(struct perf_evsel *evsel)
363{
364#define FUNCTION_EVENT "ftrace:function"
365
366 return evsel->name &&
367 !strncmp(FUNCTION_EVENT, evsel->name, sizeof(FUNCTION_EVENT));
368
369#undef FUNCTION_EVENT
370}
371 360
372static inline bool perf_evsel__is_bpf_output(struct perf_evsel *evsel) 361static inline bool perf_evsel__is_bpf_output(struct perf_evsel *evsel)
373{ 362{
@@ -431,4 +420,6 @@ typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *);
431int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, 420int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
432 attr__fprintf_f attr__fprintf, void *priv); 421 attr__fprintf_f attr__fprintf, void *priv);
433 422
423char *perf_evsel__env_arch(struct perf_evsel *evsel);
424
434#endif /* __PERF_EVSEL_H */ 425#endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/group.h b/tools/perf/util/group.h
new file mode 100644
index 000000000000..116debe7a995
--- /dev/null
+++ b/tools/perf/util/group.h
@@ -0,0 +1,7 @@
1#ifndef GROUP_H
2#define GROUP_H 1
3
4bool arch_topdown_check_group(bool *warn);
5void arch_topdown_group_warn(void);
6
7#endif
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 08852dde1378..8f0db4007282 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -336,7 +336,7 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused,
336 if (ret < 0) 336 if (ret < 0)
337 return ret; 337 return ret;
338 338
339 evlist__for_each(evlist, evsel) { 339 evlist__for_each_entry(evlist, evsel) {
340 ret = do_write(fd, &evsel->attr, sz); 340 ret = do_write(fd, &evsel->attr, sz);
341 if (ret < 0) 341 if (ret < 0)
342 return ret; 342 return ret;
@@ -801,7 +801,7 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
801 if (ret < 0) 801 if (ret < 0)
802 return ret; 802 return ret;
803 803
804 evlist__for_each(evlist, evsel) { 804 evlist__for_each_entry(evlist, evsel) {
805 if (perf_evsel__is_group_leader(evsel) && 805 if (perf_evsel__is_group_leader(evsel) &&
806 evsel->nr_members > 1) { 806 evsel->nr_members > 1) {
807 const char *name = evsel->group_name ?: "{anon_group}"; 807 const char *name = evsel->group_name ?: "{anon_group}";
@@ -1306,42 +1306,19 @@ static void print_total_mem(struct perf_header *ph, int fd __maybe_unused,
1306static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused, 1306static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused,
1307 FILE *fp) 1307 FILE *fp)
1308{ 1308{
1309 u32 nr, c, i; 1309 int i;
1310 char *str, *tmp; 1310 struct numa_node *n;
1311 uint64_t mem_total, mem_free;
1312
1313 /* nr nodes */
1314 nr = ph->env.nr_numa_nodes;
1315 str = ph->env.numa_nodes;
1316
1317 for (i = 0; i < nr; i++) {
1318 /* node number */
1319 c = strtoul(str, &tmp, 0);
1320 if (*tmp != ':')
1321 goto error;
1322
1323 str = tmp + 1;
1324 mem_total = strtoull(str, &tmp, 0);
1325 if (*tmp != ':')
1326 goto error;
1327 1311
1328 str = tmp + 1; 1312 for (i = 0; i < ph->env.nr_numa_nodes; i++) {
1329 mem_free = strtoull(str, &tmp, 0); 1313 n = &ph->env.numa_nodes[i];
1330 if (*tmp != ':')
1331 goto error;
1332 1314
1333 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB," 1315 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB,"
1334 " free = %"PRIu64" kB\n", 1316 " free = %"PRIu64" kB\n",
1335 c, mem_total, mem_free); 1317 n->node, n->mem_total, n->mem_free);
1336 1318
1337 str = tmp + 1; 1319 fprintf(fp, "# node%u cpu list : ", n->node);
1338 fprintf(fp, "# node%u cpu list : %s\n", c, str); 1320 cpu_map__fprintf(n->map, fp);
1339
1340 str += strlen(str) + 1;
1341 } 1321 }
1342 return;
1343error:
1344 fprintf(fp, "# numa topology : not available\n");
1345} 1322}
1346 1323
1347static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp) 1324static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
@@ -1425,7 +1402,7 @@ static void print_group_desc(struct perf_header *ph, int fd __maybe_unused,
1425 1402
1426 session = container_of(ph, struct perf_session, header); 1403 session = container_of(ph, struct perf_session, header);
1427 1404
1428 evlist__for_each(session->evlist, evsel) { 1405 evlist__for_each_entry(session->evlist, evsel) {
1429 if (perf_evsel__is_group_leader(evsel) && 1406 if (perf_evsel__is_group_leader(evsel) &&
1430 evsel->nr_members > 1) { 1407 evsel->nr_members > 1) {
1431 fprintf(fp, "# group: %s{%s", evsel->group_name ?: "", 1408 fprintf(fp, "# group: %s{%s", evsel->group_name ?: "",
@@ -1703,7 +1680,7 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
1703{ 1680{
1704 struct perf_evsel *evsel; 1681 struct perf_evsel *evsel;
1705 1682
1706 evlist__for_each(evlist, evsel) { 1683 evlist__for_each_entry(evlist, evsel) {
1707 if (evsel->idx == idx) 1684 if (evsel->idx == idx)
1708 return evsel; 1685 return evsel;
1709 } 1686 }
@@ -1906,11 +1883,10 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse
1906 struct perf_header *ph, int fd, 1883 struct perf_header *ph, int fd,
1907 void *data __maybe_unused) 1884 void *data __maybe_unused)
1908{ 1885{
1886 struct numa_node *nodes, *n;
1909 ssize_t ret; 1887 ssize_t ret;
1910 u32 nr, node, i; 1888 u32 nr, i;
1911 char *str; 1889 char *str;
1912 uint64_t mem_total, mem_free;
1913 struct strbuf sb;
1914 1890
1915 /* nr nodes */ 1891 /* nr nodes */
1916 ret = readn(fd, &nr, sizeof(nr)); 1892 ret = readn(fd, &nr, sizeof(nr));
@@ -1921,47 +1897,47 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse
1921 nr = bswap_32(nr); 1897 nr = bswap_32(nr);
1922 1898
1923 ph->env.nr_numa_nodes = nr; 1899 ph->env.nr_numa_nodes = nr;
1924 if (strbuf_init(&sb, 256) < 0) 1900 nodes = zalloc(sizeof(*nodes) * nr);
1925 return -1; 1901 if (!nodes)
1902 return -ENOMEM;
1926 1903
1927 for (i = 0; i < nr; i++) { 1904 for (i = 0; i < nr; i++) {
1905 n = &nodes[i];
1906
1928 /* node number */ 1907 /* node number */
1929 ret = readn(fd, &node, sizeof(node)); 1908 ret = readn(fd, &n->node, sizeof(u32));
1930 if (ret != sizeof(node)) 1909 if (ret != sizeof(n->node))
1931 goto error; 1910 goto error;
1932 1911
1933 ret = readn(fd, &mem_total, sizeof(u64)); 1912 ret = readn(fd, &n->mem_total, sizeof(u64));
1934 if (ret != sizeof(u64)) 1913 if (ret != sizeof(u64))
1935 goto error; 1914 goto error;
1936 1915
1937 ret = readn(fd, &mem_free, sizeof(u64)); 1916 ret = readn(fd, &n->mem_free, sizeof(u64));
1938 if (ret != sizeof(u64)) 1917 if (ret != sizeof(u64))
1939 goto error; 1918 goto error;
1940 1919
1941 if (ph->needs_swap) { 1920 if (ph->needs_swap) {
1942 node = bswap_32(node); 1921 n->node = bswap_32(n->node);
1943 mem_total = bswap_64(mem_total); 1922 n->mem_total = bswap_64(n->mem_total);
1944 mem_free = bswap_64(mem_free); 1923 n->mem_free = bswap_64(n->mem_free);
1945 } 1924 }
1946 1925
1947 if (strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":",
1948 node, mem_total, mem_free) < 0)
1949 goto error;
1950
1951 str = do_read_string(fd, ph); 1926 str = do_read_string(fd, ph);
1952 if (!str) 1927 if (!str)
1953 goto error; 1928 goto error;
1954 1929
1955 /* include a NULL character at the end */ 1930 n->map = cpu_map__new(str);
1956 if (strbuf_add(&sb, str, strlen(str) + 1) < 0) 1931 if (!n->map)
1957 goto error; 1932 goto error;
1933
1958 free(str); 1934 free(str);
1959 } 1935 }
1960 ph->env.numa_nodes = strbuf_detach(&sb, NULL); 1936 ph->env.numa_nodes = nodes;
1961 return 0; 1937 return 0;
1962 1938
1963error: 1939error:
1964 strbuf_release(&sb); 1940 free(nodes);
1965 return -1; 1941 return -1;
1966} 1942}
1967 1943
@@ -2075,7 +2051,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
2075 session->evlist->nr_groups = nr_groups; 2051 session->evlist->nr_groups = nr_groups;
2076 2052
2077 i = nr = 0; 2053 i = nr = 0;
2078 evlist__for_each(session->evlist, evsel) { 2054 evlist__for_each_entry(session->evlist, evsel) {
2079 if (evsel->idx == (int) desc[i].leader_idx) { 2055 if (evsel->idx == (int) desc[i].leader_idx) {
2080 evsel->leader = evsel; 2056 evsel->leader = evsel;
2081 /* {anon_group} is a dummy name */ 2057 /* {anon_group} is a dummy name */
@@ -2383,7 +2359,7 @@ int perf_session__write_header(struct perf_session *session,
2383 2359
2384 lseek(fd, sizeof(f_header), SEEK_SET); 2360 lseek(fd, sizeof(f_header), SEEK_SET);
2385 2361
2386 evlist__for_each(session->evlist, evsel) { 2362 evlist__for_each_entry(session->evlist, evsel) {
2387 evsel->id_offset = lseek(fd, 0, SEEK_CUR); 2363 evsel->id_offset = lseek(fd, 0, SEEK_CUR);
2388 err = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); 2364 err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
2389 if (err < 0) { 2365 if (err < 0) {
@@ -2394,7 +2370,7 @@ int perf_session__write_header(struct perf_session *session,
2394 2370
2395 attr_offset = lseek(fd, 0, SEEK_CUR); 2371 attr_offset = lseek(fd, 0, SEEK_CUR);
2396 2372
2397 evlist__for_each(evlist, evsel) { 2373 evlist__for_each_entry(evlist, evsel) {
2398 f_attr = (struct perf_file_attr){ 2374 f_attr = (struct perf_file_attr){
2399 .attr = evsel->attr, 2375 .attr = evsel->attr,
2400 .ids = { 2376 .ids = {
@@ -2828,7 +2804,7 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
2828{ 2804{
2829 struct perf_evsel *pos; 2805 struct perf_evsel *pos;
2830 2806
2831 evlist__for_each(evlist, pos) { 2807 evlist__for_each_entry(evlist, pos) {
2832 if (pos->attr.type == PERF_TYPE_TRACEPOINT && 2808 if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
2833 perf_evsel__prepare_tracepoint_event(pos, pevent)) 2809 perf_evsel__prepare_tracepoint_event(pos, pevent))
2834 return -1; 2810 return -1;
@@ -3127,7 +3103,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
3127 struct perf_evsel *evsel; 3103 struct perf_evsel *evsel;
3128 int err = 0; 3104 int err = 0;
3129 3105
3130 evlist__for_each(session->evlist, evsel) { 3106 evlist__for_each_entry(session->evlist, evsel) {
3131 err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids, 3107 err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids,
3132 evsel->id, process); 3108 evsel->id, process);
3133 if (err) { 3109 if (err) {
diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c
index d62ccaeeadd6..2821f8d77e52 100644
--- a/tools/perf/util/help-unknown-cmd.c
+++ b/tools/perf/util/help-unknown-cmd.c
@@ -1,4 +1,6 @@
1#include "cache.h" 1#include "cache.h"
2#include "config.h"
3#include <stdio.h>
2#include <subcmd/help.h> 4#include <subcmd/help.h>
3#include "../builtin.h" 5#include "../builtin.h"
4#include "levenshtein.h" 6#include "levenshtein.h"
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index d1f19e0012d4..a18d142cdca3 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -79,7 +79,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
79 79
80 len = thread__comm_len(h->thread); 80 len = thread__comm_len(h->thread);
81 if (hists__new_col_len(hists, HISTC_COMM, len)) 81 if (hists__new_col_len(hists, HISTC_COMM, len))
82 hists__set_col_len(hists, HISTC_THREAD, len + 6); 82 hists__set_col_len(hists, HISTC_THREAD, len + 8);
83 83
84 if (h->ms.map) { 84 if (h->ms.map) {
85 len = dso__name_len(h->ms.map->dso); 85 len = dso__name_len(h->ms.map->dso);
@@ -352,86 +352,114 @@ void hists__delete_entries(struct hists *hists)
352 * histogram, sorted on item, collects periods 352 * histogram, sorted on item, collects periods
353 */ 353 */
354 354
355static struct hist_entry *hist_entry__new(struct hist_entry *template, 355static int hist_entry__init(struct hist_entry *he,
356 bool sample_self) 356 struct hist_entry *template,
357 bool sample_self)
357{ 358{
358 size_t callchain_size = 0; 359 *he = *template;
359 struct hist_entry *he;
360 360
361 if (symbol_conf.use_callchain) 361 if (symbol_conf.cumulate_callchain) {
362 callchain_size = sizeof(struct callchain_root); 362 he->stat_acc = malloc(sizeof(he->stat));
363 if (he->stat_acc == NULL)
364 return -ENOMEM;
365 memcpy(he->stat_acc, &he->stat, sizeof(he->stat));
366 if (!sample_self)
367 memset(&he->stat, 0, sizeof(he->stat));
368 }
363 369
364 he = zalloc(sizeof(*he) + callchain_size); 370 map__get(he->ms.map);
365 371
366 if (he != NULL) { 372 if (he->branch_info) {
367 *he = *template; 373 /*
374 * This branch info is (a part of) allocated from
375 * sample__resolve_bstack() and will be freed after
376 * adding new entries. So we need to save a copy.
377 */
378 he->branch_info = malloc(sizeof(*he->branch_info));
379 if (he->branch_info == NULL) {
380 map__zput(he->ms.map);
381 free(he->stat_acc);
382 return -ENOMEM;
383 }
384
385 memcpy(he->branch_info, template->branch_info,
386 sizeof(*he->branch_info));
387
388 map__get(he->branch_info->from.map);
389 map__get(he->branch_info->to.map);
390 }
368 391
369 if (symbol_conf.cumulate_callchain) { 392 if (he->mem_info) {
370 he->stat_acc = malloc(sizeof(he->stat)); 393 map__get(he->mem_info->iaddr.map);
371 if (he->stat_acc == NULL) { 394 map__get(he->mem_info->daddr.map);
372 free(he); 395 }
373 return NULL; 396
397 if (symbol_conf.use_callchain)
398 callchain_init(he->callchain);
399
400 if (he->raw_data) {
401 he->raw_data = memdup(he->raw_data, he->raw_size);
402
403 if (he->raw_data == NULL) {
404 map__put(he->ms.map);
405 if (he->branch_info) {
406 map__put(he->branch_info->from.map);
407 map__put(he->branch_info->to.map);
408 free(he->branch_info);
409 }
410 if (he->mem_info) {
411 map__put(he->mem_info->iaddr.map);
412 map__put(he->mem_info->daddr.map);
374 } 413 }
375 memcpy(he->stat_acc, &he->stat, sizeof(he->stat)); 414 free(he->stat_acc);
376 if (!sample_self) 415 return -ENOMEM;
377 memset(&he->stat, 0, sizeof(he->stat));
378 } 416 }
417 }
418 INIT_LIST_HEAD(&he->pairs.node);
419 thread__get(he->thread);
379 420
380 map__get(he->ms.map); 421 if (!symbol_conf.report_hierarchy)
422 he->leaf = true;
381 423
382 if (he->branch_info) { 424 return 0;
383 /* 425}
384 * This branch info is (a part of) allocated from
385 * sample__resolve_bstack() and will be freed after
386 * adding new entries. So we need to save a copy.
387 */
388 he->branch_info = malloc(sizeof(*he->branch_info));
389 if (he->branch_info == NULL) {
390 map__zput(he->ms.map);
391 free(he->stat_acc);
392 free(he);
393 return NULL;
394 }
395 426
396 memcpy(he->branch_info, template->branch_info, 427static void *hist_entry__zalloc(size_t size)
397 sizeof(*he->branch_info)); 428{
429 return zalloc(size + sizeof(struct hist_entry));
430}
398 431
399 map__get(he->branch_info->from.map); 432static void hist_entry__free(void *ptr)
400 map__get(he->branch_info->to.map); 433{
401 } 434 free(ptr);
435}
402 436
403 if (he->mem_info) { 437static struct hist_entry_ops default_ops = {
404 map__get(he->mem_info->iaddr.map); 438 .new = hist_entry__zalloc,
405 map__get(he->mem_info->daddr.map); 439 .free = hist_entry__free,
406 } 440};
407 441
408 if (symbol_conf.use_callchain) 442static struct hist_entry *hist_entry__new(struct hist_entry *template,
409 callchain_init(he->callchain); 443 bool sample_self)
444{
445 struct hist_entry_ops *ops = template->ops;
446 size_t callchain_size = 0;
447 struct hist_entry *he;
448 int err = 0;
410 449
411 if (he->raw_data) { 450 if (!ops)
412 he->raw_data = memdup(he->raw_data, he->raw_size); 451 ops = template->ops = &default_ops;
413 452
414 if (he->raw_data == NULL) { 453 if (symbol_conf.use_callchain)
415 map__put(he->ms.map); 454 callchain_size = sizeof(struct callchain_root);
416 if (he->branch_info) {
417 map__put(he->branch_info->from.map);
418 map__put(he->branch_info->to.map);
419 free(he->branch_info);
420 }
421 if (he->mem_info) {
422 map__put(he->mem_info->iaddr.map);
423 map__put(he->mem_info->daddr.map);
424 }
425 free(he->stat_acc);
426 free(he);
427 return NULL;
428 }
429 }
430 INIT_LIST_HEAD(&he->pairs.node);
431 thread__get(he->thread);
432 455
433 if (!symbol_conf.report_hierarchy) 456 he = ops->new(callchain_size);
434 he->leaf = true; 457 if (he) {
458 err = hist_entry__init(he, template, sample_self);
459 if (err) {
460 ops->free(he);
461 he = NULL;
462 }
435 } 463 }
436 464
437 return he; 465 return he;
@@ -531,13 +559,15 @@ out:
531 return he; 559 return he;
532} 560}
533 561
534struct hist_entry *__hists__add_entry(struct hists *hists, 562static struct hist_entry*
535 struct addr_location *al, 563__hists__add_entry(struct hists *hists,
536 struct symbol *sym_parent, 564 struct addr_location *al,
537 struct branch_info *bi, 565 struct symbol *sym_parent,
538 struct mem_info *mi, 566 struct branch_info *bi,
539 struct perf_sample *sample, 567 struct mem_info *mi,
540 bool sample_self) 568 struct perf_sample *sample,
569 bool sample_self,
570 struct hist_entry_ops *ops)
541{ 571{
542 struct hist_entry entry = { 572 struct hist_entry entry = {
543 .thread = al->thread, 573 .thread = al->thread,
@@ -564,11 +594,37 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
564 .transaction = sample->transaction, 594 .transaction = sample->transaction,
565 .raw_data = sample->raw_data, 595 .raw_data = sample->raw_data,
566 .raw_size = sample->raw_size, 596 .raw_size = sample->raw_size,
597 .ops = ops,
567 }; 598 };
568 599
569 return hists__findnew_entry(hists, &entry, al, sample_self); 600 return hists__findnew_entry(hists, &entry, al, sample_self);
570} 601}
571 602
603struct hist_entry *hists__add_entry(struct hists *hists,
604 struct addr_location *al,
605 struct symbol *sym_parent,
606 struct branch_info *bi,
607 struct mem_info *mi,
608 struct perf_sample *sample,
609 bool sample_self)
610{
611 return __hists__add_entry(hists, al, sym_parent, bi, mi,
612 sample, sample_self, NULL);
613}
614
615struct hist_entry *hists__add_entry_ops(struct hists *hists,
616 struct hist_entry_ops *ops,
617 struct addr_location *al,
618 struct symbol *sym_parent,
619 struct branch_info *bi,
620 struct mem_info *mi,
621 struct perf_sample *sample,
622 bool sample_self)
623{
624 return __hists__add_entry(hists, al, sym_parent, bi, mi,
625 sample, sample_self, ops);
626}
627
572static int 628static int
573iter_next_nop_entry(struct hist_entry_iter *iter __maybe_unused, 629iter_next_nop_entry(struct hist_entry_iter *iter __maybe_unused,
574 struct addr_location *al __maybe_unused) 630 struct addr_location *al __maybe_unused)
@@ -622,8 +678,8 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al
622 */ 678 */
623 sample->period = cost; 679 sample->period = cost;
624 680
625 he = __hists__add_entry(hists, al, iter->parent, NULL, mi, 681 he = hists__add_entry(hists, al, iter->parent, NULL, mi,
626 sample, true); 682 sample, true);
627 if (!he) 683 if (!he)
628 return -ENOMEM; 684 return -ENOMEM;
629 685
@@ -727,8 +783,8 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
727 sample->period = 1; 783 sample->period = 1;
728 sample->weight = bi->flags.cycles ? bi->flags.cycles : 1; 784 sample->weight = bi->flags.cycles ? bi->flags.cycles : 1;
729 785
730 he = __hists__add_entry(hists, al, iter->parent, &bi[i], NULL, 786 he = hists__add_entry(hists, al, iter->parent, &bi[i], NULL,
731 sample, true); 787 sample, true);
732 if (he == NULL) 788 if (he == NULL)
733 return -ENOMEM; 789 return -ENOMEM;
734 790
@@ -764,8 +820,8 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location
764 struct perf_sample *sample = iter->sample; 820 struct perf_sample *sample = iter->sample;
765 struct hist_entry *he; 821 struct hist_entry *he;
766 822
767 he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL, 823 he = hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL,
768 sample, true); 824 sample, true);
769 if (he == NULL) 825 if (he == NULL)
770 return -ENOMEM; 826 return -ENOMEM;
771 827
@@ -825,8 +881,8 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
825 struct hist_entry *he; 881 struct hist_entry *he;
826 int err = 0; 882 int err = 0;
827 883
828 he = __hists__add_entry(hists, al, iter->parent, NULL, NULL, 884 he = hists__add_entry(hists, al, iter->parent, NULL, NULL,
829 sample, true); 885 sample, true);
830 if (he == NULL) 886 if (he == NULL)
831 return -ENOMEM; 887 return -ENOMEM;
832 888
@@ -900,8 +956,8 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
900 } 956 }
901 } 957 }
902 958
903 he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL, 959 he = hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL,
904 sample, false); 960 sample, false);
905 if (he == NULL) 961 if (he == NULL)
906 return -ENOMEM; 962 return -ENOMEM;
907 963
@@ -1043,6 +1099,8 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
1043 1099
1044void hist_entry__delete(struct hist_entry *he) 1100void hist_entry__delete(struct hist_entry *he)
1045{ 1101{
1102 struct hist_entry_ops *ops = he->ops;
1103
1046 thread__zput(he->thread); 1104 thread__zput(he->thread);
1047 map__zput(he->ms.map); 1105 map__zput(he->ms.map);
1048 1106
@@ -1067,7 +1125,7 @@ void hist_entry__delete(struct hist_entry *he)
1067 free_callchain(he->callchain); 1125 free_callchain(he->callchain);
1068 free(he->trace_output); 1126 free(he->trace_output);
1069 free(he->raw_data); 1127 free(he->raw_data);
1070 free(he); 1128 ops->free(he);
1071} 1129}
1072 1130
1073/* 1131/*
@@ -1081,7 +1139,7 @@ int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp,
1081 struct perf_hpp_fmt *fmt, int printed) 1139 struct perf_hpp_fmt *fmt, int printed)
1082{ 1140{
1083 if (!list_is_last(&fmt->list, &he->hists->hpp_list->fields)) { 1141 if (!list_is_last(&fmt->list, &he->hists->hpp_list->fields)) {
1084 const int width = fmt->width(fmt, hpp, hists_to_evsel(he->hists)); 1142 const int width = fmt->width(fmt, hpp, he->hists);
1085 if (printed < width) { 1143 if (printed < width) {
1086 advance_hpp(hpp, printed); 1144 advance_hpp(hpp, printed);
1087 printed = scnprintf(hpp->buf, hpp->size, "%-*s", width - printed, " "); 1145 printed = scnprintf(hpp->buf, hpp->size, "%-*s", width - printed, " ");
@@ -2199,7 +2257,7 @@ size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp)
2199 struct perf_evsel *pos; 2257 struct perf_evsel *pos;
2200 size_t ret = 0; 2258 size_t ret = 0;
2201 2259
2202 evlist__for_each(evlist, pos) { 2260 evlist__for_each_entry(evlist, pos) {
2203 ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); 2261 ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
2204 ret += events_stats__fprintf(&evsel__hists(pos)->stats, fp); 2262 ret += events_stats__fprintf(&evsel__hists(pos)->stats, fp);
2205 } 2263 }
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 7b54ccf1b737..49aa4fac148f 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -10,6 +10,7 @@
10#include "ui/progress.h" 10#include "ui/progress.h"
11 11
12struct hist_entry; 12struct hist_entry;
13struct hist_entry_ops;
13struct addr_location; 14struct addr_location;
14struct symbol; 15struct symbol;
15 16
@@ -120,13 +121,23 @@ extern const struct hist_iter_ops hist_iter_branch;
120extern const struct hist_iter_ops hist_iter_mem; 121extern const struct hist_iter_ops hist_iter_mem;
121extern const struct hist_iter_ops hist_iter_cumulative; 122extern const struct hist_iter_ops hist_iter_cumulative;
122 123
123struct hist_entry *__hists__add_entry(struct hists *hists, 124struct hist_entry *hists__add_entry(struct hists *hists,
124 struct addr_location *al, 125 struct addr_location *al,
125 struct symbol *parent, 126 struct symbol *parent,
126 struct branch_info *bi, 127 struct branch_info *bi,
127 struct mem_info *mi, 128 struct mem_info *mi,
128 struct perf_sample *sample, 129 struct perf_sample *sample,
129 bool sample_self); 130 bool sample_self);
131
132struct hist_entry *hists__add_entry_ops(struct hists *hists,
133 struct hist_entry_ops *ops,
134 struct addr_location *al,
135 struct symbol *sym_parent,
136 struct branch_info *bi,
137 struct mem_info *mi,
138 struct perf_sample *sample,
139 bool sample_self);
140
130int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, 141int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
131 int max_stack_depth, void *arg); 142 int max_stack_depth, void *arg);
132 143
@@ -159,7 +170,8 @@ void events_stats__inc(struct events_stats *stats, u32 type);
159size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); 170size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
160 171
161size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 172size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
162 int max_cols, float min_pcnt, FILE *fp); 173 int max_cols, float min_pcnt, FILE *fp,
174 bool use_callchain);
163size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp); 175size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp);
164 176
165void hists__filter_by_dso(struct hists *hists); 177void hists__filter_by_dso(struct hists *hists);
@@ -214,9 +226,9 @@ struct perf_hpp {
214struct perf_hpp_fmt { 226struct perf_hpp_fmt {
215 const char *name; 227 const char *name;
216 int (*header)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 228 int (*header)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
217 struct perf_evsel *evsel); 229 struct hists *hists);
218 int (*width)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 230 int (*width)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
219 struct perf_evsel *evsel); 231 struct hists *hists);
220 int (*color)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 232 int (*color)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
221 struct hist_entry *he); 233 struct hist_entry *he);
222 int (*entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 234 int (*entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
diff --git a/tools/perf/util/include/asm/byteorder.h b/tools/perf/util/include/asm/byteorder.h
deleted file mode 100644
index 2a9bdc066307..000000000000
--- a/tools/perf/util/include/asm/byteorder.h
+++ /dev/null
@@ -1,2 +0,0 @@
1#include <asm/types.h>
2#include "../../../../include/uapi/linux/swab.h"
diff --git a/tools/perf/util/include/asm/unistd_32.h b/tools/perf/util/include/asm/unistd_32.h
deleted file mode 100644
index 8b137891791f..000000000000
--- a/tools/perf/util/include/asm/unistd_32.h
+++ /dev/null
@@ -1 +0,0 @@
1
diff --git a/tools/perf/util/include/asm/unistd_64.h b/tools/perf/util/include/asm/unistd_64.h
deleted file mode 100644
index 8b137891791f..000000000000
--- a/tools/perf/util/include/asm/unistd_64.h
+++ /dev/null
@@ -1 +0,0 @@
1
diff --git a/tools/perf/util/include/linux/const.h b/tools/perf/util/include/linux/const.h
deleted file mode 100644
index c10a35e1afb8..000000000000
--- a/tools/perf/util/include/linux/const.h
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../../include/uapi/linux/const.h"
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index 9df996085563..749e6f2e37ca 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -422,7 +422,8 @@ static int intel_bts_get_branch_type(struct intel_bts_queue *btsq,
422} 422}
423 423
424static int intel_bts_process_buffer(struct intel_bts_queue *btsq, 424static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
425 struct auxtrace_buffer *buffer) 425 struct auxtrace_buffer *buffer,
426 struct thread *thread)
426{ 427{
427 struct branch *branch; 428 struct branch *branch;
428 size_t sz, bsz = sizeof(struct branch); 429 size_t sz, bsz = sizeof(struct branch);
@@ -444,6 +445,12 @@ static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
444 if (!branch->from && !branch->to) 445 if (!branch->from && !branch->to)
445 continue; 446 continue;
446 intel_bts_get_branch_type(btsq, branch); 447 intel_bts_get_branch_type(btsq, branch);
448 if (btsq->bts->synth_opts.thread_stack)
449 thread_stack__event(thread, btsq->sample_flags,
450 le64_to_cpu(branch->from),
451 le64_to_cpu(branch->to),
452 btsq->intel_pt_insn.length,
453 buffer->buffer_nr + 1);
447 if (filter && !(filter & btsq->sample_flags)) 454 if (filter && !(filter & btsq->sample_flags))
448 continue; 455 continue;
449 err = intel_bts_synth_branch_sample(btsq, branch); 456 err = intel_bts_synth_branch_sample(btsq, branch);
@@ -507,12 +514,13 @@ static int intel_bts_process_queue(struct intel_bts_queue *btsq, u64 *timestamp)
507 goto out_put; 514 goto out_put;
508 } 515 }
509 516
510 if (!btsq->bts->synth_opts.callchain && thread && 517 if (!btsq->bts->synth_opts.callchain &&
518 !btsq->bts->synth_opts.thread_stack && thread &&
511 (!old_buffer || btsq->bts->sampling_mode || 519 (!old_buffer || btsq->bts->sampling_mode ||
512 (btsq->bts->snapshot_mode && !buffer->consecutive))) 520 (btsq->bts->snapshot_mode && !buffer->consecutive)))
513 thread_stack__set_trace_nr(thread, buffer->buffer_nr + 1); 521 thread_stack__set_trace_nr(thread, buffer->buffer_nr + 1);
514 522
515 err = intel_bts_process_buffer(btsq, buffer); 523 err = intel_bts_process_buffer(btsq, buffer, thread);
516 524
517 auxtrace_buffer__drop_data(buffer); 525 auxtrace_buffer__drop_data(buffer);
518 526
@@ -777,7 +785,7 @@ static int intel_bts_synth_events(struct intel_bts *bts,
777 u64 id; 785 u64 id;
778 int err; 786 int err;
779 787
780 evlist__for_each(evlist, evsel) { 788 evlist__for_each_entry(evlist, evsel) {
781 if (evsel->attr.type == bts->pmu_type && evsel->ids) { 789 if (evsel->attr.type == bts->pmu_type && evsel->ids) {
782 found = true; 790 found = true;
783 break; 791 break;
@@ -905,10 +913,14 @@ int intel_bts_process_auxtrace_info(union perf_event *event,
905 if (dump_trace) 913 if (dump_trace)
906 return 0; 914 return 0;
907 915
908 if (session->itrace_synth_opts && session->itrace_synth_opts->set) 916 if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
909 bts->synth_opts = *session->itrace_synth_opts; 917 bts->synth_opts = *session->itrace_synth_opts;
910 else 918 } else {
911 itrace_synth_opts__set_default(&bts->synth_opts); 919 itrace_synth_opts__set_default(&bts->synth_opts);
920 if (session->itrace_synth_opts)
921 bts->synth_opts.thread_stack =
922 session->itrace_synth_opts->thread_stack;
923 }
912 924
913 if (bts->synth_opts.calls) 925 if (bts->synth_opts.calls)
914 bts->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | 926 bts->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build
index 0611d619a42e..9b742ea8bfe8 100644
--- a/tools/perf/util/intel-pt-decoder/Build
+++ b/tools/perf/util/intel-pt-decoder/Build
@@ -7,8 +7,11 @@ $(OUTPUT)util/intel-pt-decoder/inat-tables.c: $(inat_tables_script) $(inat_table
7 $(call rule_mkdir) 7 $(call rule_mkdir)
8 @$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ || rm -f $@ 8 @$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ || rm -f $@
9 9
10# Busybox's diff doesn't have -I, avoid warning in the case
11
10$(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/intel-pt-insn-decoder.c util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c 12$(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/intel-pt-insn-decoder.c util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c
11 @(test -d ../../kernel -a -d ../../tools -a -d ../perf && (( \ 13 @(diff -I 2>&1 | grep -q 'option requires an argument' && \
14 test -d ../../kernel -a -d ../../tools -a -d ../perf && (( \
12 diff -B -I'^#include' util/intel-pt-decoder/insn.c ../../arch/x86/lib/insn.c >/dev/null && \ 15 diff -B -I'^#include' util/intel-pt-decoder/insn.c ../../arch/x86/lib/insn.c >/dev/null && \
13 diff -B -I'^#include' util/intel-pt-decoder/inat.c ../../arch/x86/lib/inat.c >/dev/null && \ 16 diff -B -I'^#include' util/intel-pt-decoder/inat.c ../../arch/x86/lib/inat.c >/dev/null && \
14 diff -B util/intel-pt-decoder/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \ 17 diff -B util/intel-pt-decoder/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \
diff --git a/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk b/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk
index 517567347aac..54e961659514 100644
--- a/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk
+++ b/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk
@@ -72,12 +72,14 @@ BEGIN {
72 lprefix_expr = "\\((66|F2|F3)\\)" 72 lprefix_expr = "\\((66|F2|F3)\\)"
73 max_lprefix = 4 73 max_lprefix = 4
74 74
75 # All opcodes starting with lower-case 'v' or with (v1) superscript 75 # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
76 # accepts VEX prefix 76 # accepts VEX prefix
77 vexok_opcode_expr = "^v.*" 77 vexok_opcode_expr = "^[vk].*"
78 vexok_expr = "\\(v1\\)" 78 vexok_expr = "\\(v1\\)"
79 # All opcodes with (v) superscript supports *only* VEX prefix 79 # All opcodes with (v) superscript supports *only* VEX prefix
80 vexonly_expr = "\\(v\\)" 80 vexonly_expr = "\\(v\\)"
81 # All opcodes with (ev) superscript supports *only* EVEX prefix
82 evexonly_expr = "\\(ev\\)"
81 83
82 prefix_expr = "\\(Prefix\\)" 84 prefix_expr = "\\(Prefix\\)"
83 prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" 85 prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
@@ -95,6 +97,7 @@ BEGIN {
95 prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" 97 prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
96 prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" 98 prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
97 prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" 99 prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
100 prefix_num["EVEX"] = "INAT_PFX_EVEX"
98 101
99 clear_vars() 102 clear_vars()
100} 103}
@@ -319,7 +322,9 @@ function convert_operands(count,opnd, i,j,imm,mod)
319 flags = add_flags(flags, "INAT_MODRM") 322 flags = add_flags(flags, "INAT_MODRM")
320 323
321 # check VEX codes 324 # check VEX codes
322 if (match(ext, vexonly_expr)) 325 if (match(ext, evexonly_expr))
326 flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
327 else if (match(ext, vexonly_expr))
323 flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") 328 flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
324 else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) 329 else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
325 flags = add_flags(flags, "INAT_VEXOK") 330 flags = add_flags(flags, "INAT_VEXOK")
diff --git a/tools/perf/util/intel-pt-decoder/inat.h b/tools/perf/util/intel-pt-decoder/inat.h
index 611645e903a8..125ecd2a300d 100644
--- a/tools/perf/util/intel-pt-decoder/inat.h
+++ b/tools/perf/util/intel-pt-decoder/inat.h
@@ -48,6 +48,7 @@
48/* AVX VEX prefixes */ 48/* AVX VEX prefixes */
49#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ 49#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
50#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ 50#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
51#define INAT_PFX_EVEX 15 /* EVEX prefix */
51 52
52#define INAT_LSTPFX_MAX 3 53#define INAT_LSTPFX_MAX 3
53#define INAT_LGCPFX_MAX 11 54#define INAT_LGCPFX_MAX 11
@@ -89,6 +90,7 @@
89#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) 90#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
90#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) 91#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
91#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) 92#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
93#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
92/* Attribute making macros for attribute tables */ 94/* Attribute making macros for attribute tables */
93#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) 95#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
94#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) 96#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
141static inline int inat_is_vex_prefix(insn_attr_t attr) 143static inline int inat_is_vex_prefix(insn_attr_t attr)
142{ 144{
143 attr &= INAT_PFX_MASK; 145 attr &= INAT_PFX_MASK;
144 return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3; 146 return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
147 attr == INAT_PFX_EVEX;
148}
149
150static inline int inat_is_evex_prefix(insn_attr_t attr)
151{
152 return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
145} 153}
146 154
147static inline int inat_is_vex3_prefix(insn_attr_t attr) 155static inline int inat_is_vex3_prefix(insn_attr_t attr)
@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_attr_t attr)
216 224
217static inline int inat_must_vex(insn_attr_t attr) 225static inline int inat_must_vex(insn_attr_t attr)
218{ 226{
219 return attr & INAT_VEXONLY; 227 return attr & (INAT_VEXONLY | INAT_EVEXONLY);
228}
229
230static inline int inat_must_evex(insn_attr_t attr)
231{
232 return attr & INAT_EVEXONLY;
220} 233}
221#endif 234#endif
diff --git a/tools/perf/util/intel-pt-decoder/insn.c b/tools/perf/util/intel-pt-decoder/insn.c
index 9f26eae6c9f0..ca983e2bea8b 100644
--- a/tools/perf/util/intel-pt-decoder/insn.c
+++ b/tools/perf/util/intel-pt-decoder/insn.c
@@ -155,14 +155,24 @@ found:
155 /* 155 /*
156 * In 32-bits mode, if the [7:6] bits (mod bits of 156 * In 32-bits mode, if the [7:6] bits (mod bits of
157 * ModRM) on the second byte are not 11b, it is 157 * ModRM) on the second byte are not 11b, it is
158 * LDS or LES. 158 * LDS or LES or BOUND.
159 */ 159 */
160 if (X86_MODRM_MOD(b2) != 3) 160 if (X86_MODRM_MOD(b2) != 3)
161 goto vex_end; 161 goto vex_end;
162 } 162 }
163 insn->vex_prefix.bytes[0] = b; 163 insn->vex_prefix.bytes[0] = b;
164 insn->vex_prefix.bytes[1] = b2; 164 insn->vex_prefix.bytes[1] = b2;
165 if (inat_is_vex3_prefix(attr)) { 165 if (inat_is_evex_prefix(attr)) {
166 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
167 insn->vex_prefix.bytes[2] = b2;
168 b2 = peek_nbyte_next(insn_byte_t, insn, 3);
169 insn->vex_prefix.bytes[3] = b2;
170 insn->vex_prefix.nbytes = 4;
171 insn->next_byte += 4;
172 if (insn->x86_64 && X86_VEX_W(b2))
173 /* VEX.W overrides opnd_size */
174 insn->opnd_bytes = 8;
175 } else if (inat_is_vex3_prefix(attr)) {
166 b2 = peek_nbyte_next(insn_byte_t, insn, 2); 176 b2 = peek_nbyte_next(insn_byte_t, insn, 2);
167 insn->vex_prefix.bytes[2] = b2; 177 insn->vex_prefix.bytes[2] = b2;
168 insn->vex_prefix.nbytes = 3; 178 insn->vex_prefix.nbytes = 3;
@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
221 m = insn_vex_m_bits(insn); 231 m = insn_vex_m_bits(insn);
222 p = insn_vex_p_bits(insn); 232 p = insn_vex_p_bits(insn);
223 insn->attr = inat_get_avx_attribute(op, m, p); 233 insn->attr = inat_get_avx_attribute(op, m, p);
224 if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr)) 234 if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
235 (!inat_accept_vex(insn->attr) &&
236 !inat_is_group(insn->attr)))
225 insn->attr = 0; /* This instruction is bad */ 237 insn->attr = 0; /* This instruction is bad */
226 goto end; /* VEX has only 1 byte for opcode */ 238 goto end; /* VEX has only 1 byte for opcode */
227 } 239 }
diff --git a/tools/perf/util/intel-pt-decoder/insn.h b/tools/perf/util/intel-pt-decoder/insn.h
index dd12da0f4593..e23578c7b1be 100644
--- a/tools/perf/util/intel-pt-decoder/insn.h
+++ b/tools/perf/util/intel-pt-decoder/insn.h
@@ -91,6 +91,7 @@ struct insn {
91#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ 91#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
92#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ 92#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
93/* VEX bit fields */ 93/* VEX bit fields */
94#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
94#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ 95#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
95#define X86_VEX2_M 1 /* VEX2.M always 1 */ 96#define X86_VEX2_M 1 /* VEX2.M always 1 */
96#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ 97#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct insn *insn)
133 return (insn->vex_prefix.value != 0); 134 return (insn->vex_prefix.value != 0);
134} 135}
135 136
137static inline int insn_is_evex(struct insn *insn)
138{
139 if (!insn->prefixes.got)
140 insn_get_prefixes(insn);
141 return (insn->vex_prefix.nbytes == 4);
142}
143
136/* Ensure this instruction is decoded completely */ 144/* Ensure this instruction is decoded completely */
137static inline int insn_complete(struct insn *insn) 145static inline int insn_complete(struct insn *insn)
138{ 146{
@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
144{ 152{
145 if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ 153 if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
146 return X86_VEX2_M; 154 return X86_VEX2_M;
147 else 155 else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
148 return X86_VEX3_M(insn->vex_prefix.bytes[1]); 156 return X86_VEX3_M(insn->vex_prefix.bytes[1]);
157 else /* EVEX */
158 return X86_EVEX_M(insn->vex_prefix.bytes[1]);
149} 159}
150 160
151static inline insn_byte_t insn_vex_p_bits(struct insn *insn) 161static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
diff --git a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
index d388de72eaca..767be7c76034 100644
--- a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
+++ b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
@@ -13,12 +13,17 @@
13# opcode: escape # escaped-name 13# opcode: escape # escaped-name
14# EndTable 14# EndTable
15# 15#
16# mnemonics that begin with lowercase 'v' accept a VEX or EVEX prefix
17# mnemonics that begin with lowercase 'k' accept a VEX prefix
18#
16#<group maps> 19#<group maps>
17# GrpTable: GrpXXX 20# GrpTable: GrpXXX
18# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...] 21# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
19# EndTable 22# EndTable
20# 23#
21# AVX Superscripts 24# AVX Superscripts
25# (ev): this opcode requires EVEX prefix.
26# (evo): this opcode is changed by EVEX prefix (EVEX opcode)
22# (v): this opcode requires VEX prefix. 27# (v): this opcode requires VEX prefix.
23# (v1): this opcode only supports 128bit VEX. 28# (v1): this opcode only supports 128bit VEX.
24# 29#
@@ -137,7 +142,7 @@ AVXcode:
137# 0x60 - 0x6f 142# 0x60 - 0x6f
13860: PUSHA/PUSHAD (i64) 14360: PUSHA/PUSHAD (i64)
13961: POPA/POPAD (i64) 14461: POPA/POPAD (i64)
14062: BOUND Gv,Ma (i64) 14562: BOUND Gv,Ma (i64) | EVEX (Prefix)
14163: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64) 14663: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
14264: SEG=FS (Prefix) 14764: SEG=FS (Prefix)
14365: SEG=GS (Prefix) 14865: SEG=GS (Prefix)
@@ -399,17 +404,17 @@ AVXcode: 1
3993f: 4043f:
400# 0x0f 0x40-0x4f 405# 0x0f 0x40-0x4f
40140: CMOVO Gv,Ev 40640: CMOVO Gv,Ev
40241: CMOVNO Gv,Ev 40741: CMOVNO Gv,Ev | kandw/q Vk,Hk,Uk | kandb/d Vk,Hk,Uk (66)
40342: CMOVB/C/NAE Gv,Ev 40842: CMOVB/C/NAE Gv,Ev | kandnw/q Vk,Hk,Uk | kandnb/d Vk,Hk,Uk (66)
40443: CMOVAE/NB/NC Gv,Ev 40943: CMOVAE/NB/NC Gv,Ev
40544: CMOVE/Z Gv,Ev 41044: CMOVE/Z Gv,Ev | knotw/q Vk,Uk | knotb/d Vk,Uk (66)
40645: CMOVNE/NZ Gv,Ev 41145: CMOVNE/NZ Gv,Ev | korw/q Vk,Hk,Uk | korb/d Vk,Hk,Uk (66)
40746: CMOVBE/NA Gv,Ev 41246: CMOVBE/NA Gv,Ev | kxnorw/q Vk,Hk,Uk | kxnorb/d Vk,Hk,Uk (66)
40847: CMOVA/NBE Gv,Ev 41347: CMOVA/NBE Gv,Ev | kxorw/q Vk,Hk,Uk | kxorb/d Vk,Hk,Uk (66)
40948: CMOVS Gv,Ev 41448: CMOVS Gv,Ev
41049: CMOVNS Gv,Ev 41549: CMOVNS Gv,Ev
4114a: CMOVP/PE Gv,Ev 4164a: CMOVP/PE Gv,Ev | kaddw/q Vk,Hk,Uk | kaddb/d Vk,Hk,Uk (66)
4124b: CMOVNP/PO Gv,Ev 4174b: CMOVNP/PO Gv,Ev | kunpckbw Vk,Hk,Uk (66) | kunpckwd/dq Vk,Hk,Uk
4134c: CMOVL/NGE Gv,Ev 4184c: CMOVL/NGE Gv,Ev
4144d: CMOVNL/GE Gv,Ev 4194d: CMOVNL/GE Gv,Ev
4154e: CMOVLE/NG Gv,Ev 4204e: CMOVLE/NG Gv,Ev
@@ -426,7 +431,7 @@ AVXcode: 1
42658: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1) 43158: vaddps Vps,Hps,Wps | vaddpd Vpd,Hpd,Wpd (66) | vaddss Vss,Hss,Wss (F3),(v1) | vaddsd Vsd,Hsd,Wsd (F2),(v1)
42759: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1) 43259: vmulps Vps,Hps,Wps | vmulpd Vpd,Hpd,Wpd (66) | vmulss Vss,Hss,Wss (F3),(v1) | vmulsd Vsd,Hsd,Wsd (F2),(v1)
4285a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1) 4335a: vcvtps2pd Vpd,Wps | vcvtpd2ps Vps,Wpd (66) | vcvtss2sd Vsd,Hx,Wss (F3),(v1) | vcvtsd2ss Vss,Hx,Wsd (F2),(v1)
4295b: vcvtdq2ps Vps,Wdq | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3) 4345b: vcvtdq2ps Vps,Wdq | vcvtqq2ps Vps,Wqq (evo) | vcvtps2dq Vdq,Wps (66) | vcvttps2dq Vdq,Wps (F3)
4305c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1) 4355c: vsubps Vps,Hps,Wps | vsubpd Vpd,Hpd,Wpd (66) | vsubss Vss,Hss,Wss (F3),(v1) | vsubsd Vsd,Hsd,Wsd (F2),(v1)
4315d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1) 4365d: vminps Vps,Hps,Wps | vminpd Vpd,Hpd,Wpd (66) | vminss Vss,Hss,Wss (F3),(v1) | vminsd Vsd,Hsd,Wsd (F2),(v1)
4325e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1) 4375e: vdivps Vps,Hps,Wps | vdivpd Vpd,Hpd,Wpd (66) | vdivss Vss,Hss,Wss (F3),(v1) | vdivsd Vsd,Hsd,Wsd (F2),(v1)
@@ -447,7 +452,7 @@ AVXcode: 1
4476c: vpunpcklqdq Vx,Hx,Wx (66),(v1) 4526c: vpunpcklqdq Vx,Hx,Wx (66),(v1)
4486d: vpunpckhqdq Vx,Hx,Wx (66),(v1) 4536d: vpunpckhqdq Vx,Hx,Wx (66),(v1)
4496e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1) 4546e: movd/q Pd,Ey | vmovd/q Vy,Ey (66),(v1)
4506f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqu Vx,Wx (F3) 4556f: movq Pq,Qq | vmovdqa Vx,Wx (66) | vmovdqa32/64 Vx,Wx (66),(evo) | vmovdqu Vx,Wx (F3) | vmovdqu32/64 Vx,Wx (F3),(evo) | vmovdqu8/16 Vx,Wx (F2),(ev)
451# 0x0f 0x70-0x7f 456# 0x0f 0x70-0x7f
45270: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1) 45770: pshufw Pq,Qq,Ib | vpshufd Vx,Wx,Ib (66),(v1) | vpshufhw Vx,Wx,Ib (F3),(v1) | vpshuflw Vx,Wx,Ib (F2),(v1)
45371: Grp12 (1A) 45871: Grp12 (1A)
@@ -458,14 +463,14 @@ AVXcode: 1
45876: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1) 46376: pcmpeqd Pq,Qq | vpcmpeqd Vx,Hx,Wx (66),(v1)
459# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX. 464# Note: Remove (v), because vzeroall and vzeroupper becomes emms without VEX.
46077: emms | vzeroupper | vzeroall 46577: emms | vzeroupper | vzeroall
46178: VMREAD Ey,Gy 46678: VMREAD Ey,Gy | vcvttps2udq/pd2udq Vx,Wpd (evo) | vcvttsd2usi Gv,Wx (F2),(ev) | vcvttss2usi Gv,Wx (F3),(ev) | vcvttps2uqq/pd2uqq Vx,Wx (66),(ev)
46279: VMWRITE Gy,Ey 46779: VMWRITE Gy,Ey | vcvtps2udq/pd2udq Vx,Wpd (evo) | vcvtsd2usi Gv,Wx (F2),(ev) | vcvtss2usi Gv,Wx (F3),(ev) | vcvtps2uqq/pd2uqq Vx,Wx (66),(ev)
4637a: 4687a: vcvtudq2pd/uqq2pd Vpd,Wx (F3),(ev) | vcvtudq2ps/uqq2ps Vpd,Wx (F2),(ev) | vcvttps2qq/pd2qq Vx,Wx (66),(ev)
4647b: 4697b: vcvtusi2sd Vpd,Hpd,Ev (F2),(ev) | vcvtusi2ss Vps,Hps,Ev (F3),(ev) | vcvtps2qq/pd2qq Vx,Wx (66),(ev)
4657c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2) 4707c: vhaddpd Vpd,Hpd,Wpd (66) | vhaddps Vps,Hps,Wps (F2)
4667d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2) 4717d: vhsubpd Vpd,Hpd,Wpd (66) | vhsubps Vps,Hps,Wps (F2)
4677e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1) 4727e: movd/q Ey,Pd | vmovd/q Ey,Vy (66),(v1) | vmovq Vq,Wq (F3),(v1)
4687f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqu Wx,Vx (F3) 4737f: movq Qq,Pq | vmovdqa Wx,Vx (66) | vmovdqa32/64 Wx,Vx (66),(evo) | vmovdqu Wx,Vx (F3) | vmovdqu32/64 Wx,Vx (F3),(evo) | vmovdqu8/16 Wx,Vx (F2),(ev)
469# 0x0f 0x80-0x8f 474# 0x0f 0x80-0x8f
470# Note: "forced64" is Intel CPU behavior (see comment about CALL insn). 475# Note: "forced64" is Intel CPU behavior (see comment about CALL insn).
47180: JO Jz (f64) 47680: JO Jz (f64)
@@ -485,16 +490,16 @@ AVXcode: 1
4858e: JLE/JNG Jz (f64) 4908e: JLE/JNG Jz (f64)
4868f: JNLE/JG Jz (f64) 4918f: JNLE/JG Jz (f64)
487# 0x0f 0x90-0x9f 492# 0x0f 0x90-0x9f
48890: SETO Eb 49390: SETO Eb | kmovw/q Vk,Wk | kmovb/d Vk,Wk (66)
48991: SETNO Eb 49491: SETNO Eb | kmovw/q Mv,Vk | kmovb/d Mv,Vk (66)
49092: SETB/C/NAE Eb 49592: SETB/C/NAE Eb | kmovw Vk,Rv | kmovb Vk,Rv (66) | kmovq/d Vk,Rv (F2)
49193: SETAE/NB/NC Eb 49693: SETAE/NB/NC Eb | kmovw Gv,Uk | kmovb Gv,Uk (66) | kmovq/d Gv,Uk (F2)
49294: SETE/Z Eb 49794: SETE/Z Eb
49395: SETNE/NZ Eb 49895: SETNE/NZ Eb
49496: SETBE/NA Eb 49996: SETBE/NA Eb
49597: SETA/NBE Eb 50097: SETA/NBE Eb
49698: SETS Eb 50198: SETS Eb | kortestw/q Vk,Uk | kortestb/d Vk,Uk (66)
49799: SETNS Eb 50299: SETNS Eb | ktestw/q Vk,Uk | ktestb/d Vk,Uk (66)
4989a: SETP/PE Eb 5039a: SETP/PE Eb
4999b: SETNP/PO Eb 5049b: SETNP/PO Eb
5009c: SETL/NGE Eb 5059c: SETL/NGE Eb
@@ -564,11 +569,11 @@ d7: pmovmskb Gd,Nq | vpmovmskb Gd,Ux (66),(v1)
564d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1) 569d8: psubusb Pq,Qq | vpsubusb Vx,Hx,Wx (66),(v1)
565d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1) 570d9: psubusw Pq,Qq | vpsubusw Vx,Hx,Wx (66),(v1)
566da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1) 571da: pminub Pq,Qq | vpminub Vx,Hx,Wx (66),(v1)
567db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) 572db: pand Pq,Qq | vpand Vx,Hx,Wx (66),(v1) | vpandd/q Vx,Hx,Wx (66),(evo)
568dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1) 573dc: paddusb Pq,Qq | vpaddusb Vx,Hx,Wx (66),(v1)
569dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1) 574dd: paddusw Pq,Qq | vpaddusw Vx,Hx,Wx (66),(v1)
570de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1) 575de: pmaxub Pq,Qq | vpmaxub Vx,Hx,Wx (66),(v1)
571df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) 576df: pandn Pq,Qq | vpandn Vx,Hx,Wx (66),(v1) | vpandnd/q Vx,Hx,Wx (66),(evo)
572# 0x0f 0xe0-0xef 577# 0x0f 0xe0-0xef
573e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1) 578e0: pavgb Pq,Qq | vpavgb Vx,Hx,Wx (66),(v1)
574e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1) 579e1: psraw Pq,Qq | vpsraw Vx,Hx,Wx (66),(v1)
@@ -576,16 +581,16 @@ e2: psrad Pq,Qq | vpsrad Vx,Hx,Wx (66),(v1)
576e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1) 581e3: pavgw Pq,Qq | vpavgw Vx,Hx,Wx (66),(v1)
577e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1) 582e4: pmulhuw Pq,Qq | vpmulhuw Vx,Hx,Wx (66),(v1)
578e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1) 583e5: pmulhw Pq,Qq | vpmulhw Vx,Hx,Wx (66),(v1)
579e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtpd2dq Vx,Wpd (F2) 584e6: vcvttpd2dq Vx,Wpd (66) | vcvtdq2pd Vx,Wdq (F3) | vcvtdq2pd/qq2pd Vx,Wdq (F3),(evo) | vcvtpd2dq Vx,Wpd (F2)
580e7: movntq Mq,Pq | vmovntdq Mx,Vx (66) 585e7: movntq Mq,Pq | vmovntdq Mx,Vx (66)
581e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1) 586e8: psubsb Pq,Qq | vpsubsb Vx,Hx,Wx (66),(v1)
582e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1) 587e9: psubsw Pq,Qq | vpsubsw Vx,Hx,Wx (66),(v1)
583ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1) 588ea: pminsw Pq,Qq | vpminsw Vx,Hx,Wx (66),(v1)
584eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) 589eb: por Pq,Qq | vpor Vx,Hx,Wx (66),(v1) | vpord/q Vx,Hx,Wx (66),(evo)
585ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1) 590ec: paddsb Pq,Qq | vpaddsb Vx,Hx,Wx (66),(v1)
586ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1) 591ed: paddsw Pq,Qq | vpaddsw Vx,Hx,Wx (66),(v1)
587ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1) 592ee: pmaxsw Pq,Qq | vpmaxsw Vx,Hx,Wx (66),(v1)
588ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) 593ef: pxor Pq,Qq | vpxor Vx,Hx,Wx (66),(v1) | vpxord/q Vx,Hx,Wx (66),(evo)
589# 0x0f 0xf0-0xff 594# 0x0f 0xf0-0xff
590f0: vlddqu Vx,Mx (F2) 595f0: vlddqu Vx,Mx (F2)
591f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1) 596f1: psllw Pq,Qq | vpsllw Vx,Hx,Wx (66),(v1)
@@ -626,81 +631,105 @@ AVXcode: 2
6260e: vtestps Vx,Wx (66),(v) 6310e: vtestps Vx,Wx (66),(v)
6270f: vtestpd Vx,Wx (66),(v) 6320f: vtestpd Vx,Wx (66),(v)
628# 0x0f 0x38 0x10-0x1f 633# 0x0f 0x38 0x10-0x1f
62910: pblendvb Vdq,Wdq (66) 63410: pblendvb Vdq,Wdq (66) | vpsrlvw Vx,Hx,Wx (66),(evo) | vpmovuswb Wx,Vx (F3),(ev)
63011: 63511: vpmovusdb Wx,Vd (F3),(ev) | vpsravw Vx,Hx,Wx (66),(ev)
63112: 63612: vpmovusqb Wx,Vq (F3),(ev) | vpsllvw Vx,Hx,Wx (66),(ev)
63213: vcvtph2ps Vx,Wx,Ib (66),(v) 63713: vcvtph2ps Vx,Wx (66),(v) | vpmovusdw Wx,Vd (F3),(ev)
63314: blendvps Vdq,Wdq (66) 63814: blendvps Vdq,Wdq (66) | vpmovusqw Wx,Vq (F3),(ev) | vprorvd/q Vx,Hx,Wx (66),(evo)
63415: blendvpd Vdq,Wdq (66) 63915: blendvpd Vdq,Wdq (66) | vpmovusqd Wx,Vq (F3),(ev) | vprolvd/q Vx,Hx,Wx (66),(evo)
63516: vpermps Vqq,Hqq,Wqq (66),(v) 64016: vpermps Vqq,Hqq,Wqq (66),(v) | vpermps/d Vqq,Hqq,Wqq (66),(evo)
63617: vptest Vx,Wx (66) 64117: vptest Vx,Wx (66)
63718: vbroadcastss Vx,Wd (66),(v) 64218: vbroadcastss Vx,Wd (66),(v)
63819: vbroadcastsd Vqq,Wq (66),(v) 64319: vbroadcastsd Vqq,Wq (66),(v) | vbroadcastf32x2 Vqq,Wq (66),(evo)
6391a: vbroadcastf128 Vqq,Mdq (66),(v) 6441a: vbroadcastf128 Vqq,Mdq (66),(v) | vbroadcastf32x4/64x2 Vqq,Wq (66),(evo)
6401b: 6451b: vbroadcastf32x8/64x4 Vqq,Mdq (66),(ev)
6411c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1) 6461c: pabsb Pq,Qq | vpabsb Vx,Wx (66),(v1)
6421d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1) 6471d: pabsw Pq,Qq | vpabsw Vx,Wx (66),(v1)
6431e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1) 6481e: pabsd Pq,Qq | vpabsd Vx,Wx (66),(v1)
6441f: 6491f: vpabsq Vx,Wx (66),(ev)
645# 0x0f 0x38 0x20-0x2f 650# 0x0f 0x38 0x20-0x2f
64620: vpmovsxbw Vx,Ux/Mq (66),(v1) 65120: vpmovsxbw Vx,Ux/Mq (66),(v1) | vpmovswb Wx,Vx (F3),(ev)
64721: vpmovsxbd Vx,Ux/Md (66),(v1) 65221: vpmovsxbd Vx,Ux/Md (66),(v1) | vpmovsdb Wx,Vd (F3),(ev)
64822: vpmovsxbq Vx,Ux/Mw (66),(v1) 65322: vpmovsxbq Vx,Ux/Mw (66),(v1) | vpmovsqb Wx,Vq (F3),(ev)
64923: vpmovsxwd Vx,Ux/Mq (66),(v1) 65423: vpmovsxwd Vx,Ux/Mq (66),(v1) | vpmovsdw Wx,Vd (F3),(ev)
65024: vpmovsxwq Vx,Ux/Md (66),(v1) 65524: vpmovsxwq Vx,Ux/Md (66),(v1) | vpmovsqw Wx,Vq (F3),(ev)
65125: vpmovsxdq Vx,Ux/Mq (66),(v1) 65625: vpmovsxdq Vx,Ux/Mq (66),(v1) | vpmovsqd Wx,Vq (F3),(ev)
65226: 65726: vptestmb/w Vk,Hx,Wx (66),(ev) | vptestnmb/w Vk,Hx,Wx (F3),(ev)
65327: 65827: vptestmd/q Vk,Hx,Wx (66),(ev) | vptestnmd/q Vk,Hx,Wx (F3),(ev)
65428: vpmuldq Vx,Hx,Wx (66),(v1) 65928: vpmuldq Vx,Hx,Wx (66),(v1) | vpmovm2b/w Vx,Uk (F3),(ev)
65529: vpcmpeqq Vx,Hx,Wx (66),(v1) 66029: vpcmpeqq Vx,Hx,Wx (66),(v1) | vpmovb2m/w2m Vk,Ux (F3),(ev)
6562a: vmovntdqa Vx,Mx (66),(v1) 6612a: vmovntdqa Vx,Mx (66),(v1) | vpbroadcastmb2q Vx,Uk (F3),(ev)
6572b: vpackusdw Vx,Hx,Wx (66),(v1) 6622b: vpackusdw Vx,Hx,Wx (66),(v1)
6582c: vmaskmovps Vx,Hx,Mx (66),(v) 6632c: vmaskmovps Vx,Hx,Mx (66),(v) | vscalefps/d Vx,Hx,Wx (66),(evo)
6592d: vmaskmovpd Vx,Hx,Mx (66),(v) 6642d: vmaskmovpd Vx,Hx,Mx (66),(v) | vscalefss/d Vx,Hx,Wx (66),(evo)
6602e: vmaskmovps Mx,Hx,Vx (66),(v) 6652e: vmaskmovps Mx,Hx,Vx (66),(v)
6612f: vmaskmovpd Mx,Hx,Vx (66),(v) 6662f: vmaskmovpd Mx,Hx,Vx (66),(v)
662# 0x0f 0x38 0x30-0x3f 667# 0x0f 0x38 0x30-0x3f
66330: vpmovzxbw Vx,Ux/Mq (66),(v1) 66830: vpmovzxbw Vx,Ux/Mq (66),(v1) | vpmovwb Wx,Vx (F3),(ev)
66431: vpmovzxbd Vx,Ux/Md (66),(v1) 66931: vpmovzxbd Vx,Ux/Md (66),(v1) | vpmovdb Wx,Vd (F3),(ev)
66532: vpmovzxbq Vx,Ux/Mw (66),(v1) 67032: vpmovzxbq Vx,Ux/Mw (66),(v1) | vpmovqb Wx,Vq (F3),(ev)
66633: vpmovzxwd Vx,Ux/Mq (66),(v1) 67133: vpmovzxwd Vx,Ux/Mq (66),(v1) | vpmovdw Wx,Vd (F3),(ev)
66734: vpmovzxwq Vx,Ux/Md (66),(v1) 67234: vpmovzxwq Vx,Ux/Md (66),(v1) | vpmovqw Wx,Vq (F3),(ev)
66835: vpmovzxdq Vx,Ux/Mq (66),(v1) 67335: vpmovzxdq Vx,Ux/Mq (66),(v1) | vpmovqd Wx,Vq (F3),(ev)
66936: vpermd Vqq,Hqq,Wqq (66),(v) 67436: vpermd Vqq,Hqq,Wqq (66),(v) | vpermd/q Vqq,Hqq,Wqq (66),(evo)
67037: vpcmpgtq Vx,Hx,Wx (66),(v1) 67537: vpcmpgtq Vx,Hx,Wx (66),(v1)
67138: vpminsb Vx,Hx,Wx (66),(v1) 67638: vpminsb Vx,Hx,Wx (66),(v1) | vpmovm2d/q Vx,Uk (F3),(ev)
67239: vpminsd Vx,Hx,Wx (66),(v1) 67739: vpminsd Vx,Hx,Wx (66),(v1) | vpminsd/q Vx,Hx,Wx (66),(evo) | vpmovd2m/q2m Vk,Ux (F3),(ev)
6733a: vpminuw Vx,Hx,Wx (66),(v1) 6783a: vpminuw Vx,Hx,Wx (66),(v1) | vpbroadcastmw2d Vx,Uk (F3),(ev)
6743b: vpminud Vx,Hx,Wx (66),(v1) 6793b: vpminud Vx,Hx,Wx (66),(v1) | vpminud/q Vx,Hx,Wx (66),(evo)
6753c: vpmaxsb Vx,Hx,Wx (66),(v1) 6803c: vpmaxsb Vx,Hx,Wx (66),(v1)
6763d: vpmaxsd Vx,Hx,Wx (66),(v1) 6813d: vpmaxsd Vx,Hx,Wx (66),(v1) | vpmaxsd/q Vx,Hx,Wx (66),(evo)
6773e: vpmaxuw Vx,Hx,Wx (66),(v1) 6823e: vpmaxuw Vx,Hx,Wx (66),(v1)
6783f: vpmaxud Vx,Hx,Wx (66),(v1) 6833f: vpmaxud Vx,Hx,Wx (66),(v1) | vpmaxud/q Vx,Hx,Wx (66),(evo)
679# 0x0f 0x38 0x40-0x8f 684# 0x0f 0x38 0x40-0x8f
68040: vpmulld Vx,Hx,Wx (66),(v1) 68540: vpmulld Vx,Hx,Wx (66),(v1) | vpmulld/q Vx,Hx,Wx (66),(evo)
68141: vphminposuw Vdq,Wdq (66),(v1) 68641: vphminposuw Vdq,Wdq (66),(v1)
68242: 68742: vgetexpps/d Vx,Wx (66),(ev)
68343: 68843: vgetexpss/d Vx,Hx,Wx (66),(ev)
68444: 68944: vplzcntd/q Vx,Wx (66),(ev)
68545: vpsrlvd/q Vx,Hx,Wx (66),(v) 69045: vpsrlvd/q Vx,Hx,Wx (66),(v)
68646: vpsravd Vx,Hx,Wx (66),(v) 69146: vpsravd Vx,Hx,Wx (66),(v) | vpsravd/q Vx,Hx,Wx (66),(evo)
68747: vpsllvd/q Vx,Hx,Wx (66),(v) 69247: vpsllvd/q Vx,Hx,Wx (66),(v)
688# Skip 0x48-0x57 693# Skip 0x48-0x4b
6944c: vrcp14ps/d Vpd,Wpd (66),(ev)
6954d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
6964e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
6974f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
698# Skip 0x50-0x57
68958: vpbroadcastd Vx,Wx (66),(v) 69958: vpbroadcastd Vx,Wx (66),(v)
69059: vpbroadcastq Vx,Wx (66),(v) 70059: vpbroadcastq Vx,Wx (66),(v) | vbroadcasti32x2 Vx,Wx (66),(evo)
6915a: vbroadcasti128 Vqq,Mdq (66),(v) 7015a: vbroadcasti128 Vqq,Mdq (66),(v) | vbroadcasti32x4/64x2 Vx,Wx (66),(evo)
692# Skip 0x5b-0x77 7025b: vbroadcasti32x8/64x4 Vqq,Mdq (66),(ev)
703# Skip 0x5c-0x63
70464: vpblendmd/q Vx,Hx,Wx (66),(ev)
70565: vblendmps/d Vx,Hx,Wx (66),(ev)
70666: vpblendmb/w Vx,Hx,Wx (66),(ev)
707# Skip 0x67-0x74
70875: vpermi2b/w Vx,Hx,Wx (66),(ev)
70976: vpermi2d/q Vx,Hx,Wx (66),(ev)
71077: vpermi2ps/d Vx,Hx,Wx (66),(ev)
69378: vpbroadcastb Vx,Wx (66),(v) 71178: vpbroadcastb Vx,Wx (66),(v)
69479: vpbroadcastw Vx,Wx (66),(v) 71279: vpbroadcastw Vx,Wx (66),(v)
695# Skip 0x7a-0x7f 7137a: vpbroadcastb Vx,Rv (66),(ev)
7147b: vpbroadcastw Vx,Rv (66),(ev)
7157c: vpbroadcastd/q Vx,Rv (66),(ev)
7167d: vpermt2b/w Vx,Hx,Wx (66),(ev)
7177e: vpermt2d/q Vx,Hx,Wx (66),(ev)
7187f: vpermt2ps/d Vx,Hx,Wx (66),(ev)
69680: INVEPT Gy,Mdq (66) 71980: INVEPT Gy,Mdq (66)
69781: INVPID Gy,Mdq (66) 72081: INVPID Gy,Mdq (66)
69882: INVPCID Gy,Mdq (66) 72182: INVPCID Gy,Mdq (66)
72283: vpmultishiftqb Vx,Hx,Wx (66),(ev)
72388: vexpandps/d Vpd,Wpd (66),(ev)
72489: vpexpandd/q Vx,Wx (66),(ev)
7258a: vcompressps/d Wx,Vx (66),(ev)
7268b: vpcompressd/q Wx,Vx (66),(ev)
6998c: vpmaskmovd/q Vx,Hx,Mx (66),(v) 7278c: vpmaskmovd/q Vx,Hx,Mx (66),(v)
7288d: vpermb/w Vx,Hx,Wx (66),(ev)
7008e: vpmaskmovd/q Mx,Vx,Hx (66),(v) 7298e: vpmaskmovd/q Mx,Vx,Hx (66),(v)
701# 0x0f 0x38 0x90-0xbf (FMA) 730# 0x0f 0x38 0x90-0xbf (FMA)
70290: vgatherdd/q Vx,Hx,Wx (66),(v) 73190: vgatherdd/q Vx,Hx,Wx (66),(v) | vpgatherdd/q Vx,Wx (66),(evo)
70391: vgatherqd/q Vx,Hx,Wx (66),(v) 73291: vgatherqd/q Vx,Hx,Wx (66),(v) | vpgatherqd/q Vx,Wx (66),(evo)
70492: vgatherdps/d Vx,Hx,Wx (66),(v) 73392: vgatherdps/d Vx,Hx,Wx (66),(v)
70593: vgatherqps/d Vx,Hx,Wx (66),(v) 73493: vgatherqps/d Vx,Hx,Wx (66),(v)
70694: 73594:
@@ -715,6 +744,10 @@ AVXcode: 2
7159d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1) 7449d: vfnmadd132ss/d Vx,Hx,Wx (66),(v),(v1)
7169e: vfnmsub132ps/d Vx,Hx,Wx (66),(v) 7459e: vfnmsub132ps/d Vx,Hx,Wx (66),(v)
7179f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1) 7469f: vfnmsub132ss/d Vx,Hx,Wx (66),(v),(v1)
747a0: vpscatterdd/q Wx,Vx (66),(ev)
748a1: vpscatterqd/q Wx,Vx (66),(ev)
749a2: vscatterdps/d Wx,Vx (66),(ev)
750a3: vscatterqps/d Wx,Vx (66),(ev)
718a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v) 751a6: vfmaddsub213ps/d Vx,Hx,Wx (66),(v)
719a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v) 752a7: vfmsubadd213ps/d Vx,Hx,Wx (66),(v)
720a8: vfmadd213ps/d Vx,Hx,Wx (66),(v) 753a8: vfmadd213ps/d Vx,Hx,Wx (66),(v)
@@ -725,6 +758,8 @@ ac: vfnmadd213ps/d Vx,Hx,Wx (66),(v)
725ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1) 758ad: vfnmadd213ss/d Vx,Hx,Wx (66),(v),(v1)
726ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v) 759ae: vfnmsub213ps/d Vx,Hx,Wx (66),(v)
727af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1) 760af: vfnmsub213ss/d Vx,Hx,Wx (66),(v),(v1)
761b4: vpmadd52luq Vx,Hx,Wx (66),(ev)
762b5: vpmadd52huq Vx,Hx,Wx (66),(ev)
728b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v) 763b6: vfmaddsub231ps/d Vx,Hx,Wx (66),(v)
729b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v) 764b7: vfmsubadd231ps/d Vx,Hx,Wx (66),(v)
730b8: vfmadd231ps/d Vx,Hx,Wx (66),(v) 765b8: vfmadd231ps/d Vx,Hx,Wx (66),(v)
@@ -736,12 +771,15 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
736be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) 771be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
737bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) 772bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
738# 0x0f 0x38 0xc0-0xff 773# 0x0f 0x38 0xc0-0xff
739c8: sha1nexte Vdq,Wdq 774c4: vpconflictd/q Vx,Wx (66),(ev)
775c6: Grp18 (1A)
776c7: Grp19 (1A)
777c8: sha1nexte Vdq,Wdq | vexp2ps/d Vx,Wx (66),(ev)
740c9: sha1msg1 Vdq,Wdq 778c9: sha1msg1 Vdq,Wdq
741ca: sha1msg2 Vdq,Wdq 779ca: sha1msg2 Vdq,Wdq | vrcp28ps/d Vx,Wx (66),(ev)
742cb: sha256rnds2 Vdq,Wdq 780cb: sha256rnds2 Vdq,Wdq | vrcp28ss/d Vx,Hx,Wx (66),(ev)
743cc: sha256msg1 Vdq,Wdq 781cc: sha256msg1 Vdq,Wdq | vrsqrt28ps/d Vx,Wx (66),(ev)
744cd: sha256msg2 Vdq,Wdq 782cd: sha256msg2 Vdq,Wdq | vrsqrt28ss/d Vx,Hx,Wx (66),(ev)
745db: VAESIMC Vdq,Wdq (66),(v1) 783db: VAESIMC Vdq,Wdq (66),(v1)
746dc: VAESENC Vdq,Hdq,Wdq (66),(v1) 784dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
747dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) 785dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -763,15 +801,15 @@ AVXcode: 3
76300: vpermq Vqq,Wqq,Ib (66),(v) 80100: vpermq Vqq,Wqq,Ib (66),(v)
76401: vpermpd Vqq,Wqq,Ib (66),(v) 80201: vpermpd Vqq,Wqq,Ib (66),(v)
76502: vpblendd Vx,Hx,Wx,Ib (66),(v) 80302: vpblendd Vx,Hx,Wx,Ib (66),(v)
76603: 80403: valignd/q Vx,Hx,Wx,Ib (66),(ev)
76704: vpermilps Vx,Wx,Ib (66),(v) 80504: vpermilps Vx,Wx,Ib (66),(v)
76805: vpermilpd Vx,Wx,Ib (66),(v) 80605: vpermilpd Vx,Wx,Ib (66),(v)
76906: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v) 80706: vperm2f128 Vqq,Hqq,Wqq,Ib (66),(v)
77007: 80807:
77108: vroundps Vx,Wx,Ib (66) 80908: vroundps Vx,Wx,Ib (66) | vrndscaleps Vx,Wx,Ib (66),(evo)
77209: vroundpd Vx,Wx,Ib (66) 81009: vroundpd Vx,Wx,Ib (66) | vrndscalepd Vx,Wx,Ib (66),(evo)
7730a: vroundss Vss,Wss,Ib (66),(v1) 8110a: vroundss Vss,Wss,Ib (66),(v1) | vrndscaless Vx,Hx,Wx,Ib (66),(evo)
7740b: vroundsd Vsd,Wsd,Ib (66),(v1) 8120b: vroundsd Vsd,Wsd,Ib (66),(v1) | vrndscalesd Vx,Hx,Wx,Ib (66),(evo)
7750c: vblendps Vx,Hx,Wx,Ib (66) 8130c: vblendps Vx,Hx,Wx,Ib (66)
7760d: vblendpd Vx,Hx,Wx,Ib (66) 8140d: vblendpd Vx,Hx,Wx,Ib (66)
7770e: vpblendw Vx,Hx,Wx,Ib (66),(v1) 8150e: vpblendw Vx,Hx,Wx,Ib (66),(v1)
@@ -780,26 +818,51 @@ AVXcode: 3
78015: vpextrw Rd/Mw,Vdq,Ib (66),(v1) 81815: vpextrw Rd/Mw,Vdq,Ib (66),(v1)
78116: vpextrd/q Ey,Vdq,Ib (66),(v1) 81916: vpextrd/q Ey,Vdq,Ib (66),(v1)
78217: vextractps Ed,Vdq,Ib (66),(v1) 82017: vextractps Ed,Vdq,Ib (66),(v1)
78318: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) 82118: vinsertf128 Vqq,Hqq,Wqq,Ib (66),(v) | vinsertf32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
78419: vextractf128 Wdq,Vqq,Ib (66),(v) 82219: vextractf128 Wdq,Vqq,Ib (66),(v) | vextractf32x4/64x2 Wdq,Vqq,Ib (66),(evo)
8231a: vinsertf32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
8241b: vextractf32x8/64x4 Wdq,Vqq,Ib (66),(ev)
7851d: vcvtps2ph Wx,Vx,Ib (66),(v) 8251d: vcvtps2ph Wx,Vx,Ib (66),(v)
8261e: vpcmpud/q Vk,Hd,Wd,Ib (66),(ev)
8271f: vpcmpd/q Vk,Hd,Wd,Ib (66),(ev)
78620: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1) 82820: vpinsrb Vdq,Hdq,Ry/Mb,Ib (66),(v1)
78721: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1) 82921: vinsertps Vdq,Hdq,Udq/Md,Ib (66),(v1)
78822: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1) 83022: vpinsrd/q Vdq,Hdq,Ey,Ib (66),(v1)
78938: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) 83123: vshuff32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
79039: vextracti128 Wdq,Vqq,Ib (66),(v) 83225: vpternlogd/q Vx,Hx,Wx,Ib (66),(ev)
83326: vgetmantps/d Vx,Wx,Ib (66),(ev)
83427: vgetmantss/d Vx,Hx,Wx,Ib (66),(ev)
83530: kshiftrb/w Vk,Uk,Ib (66),(v)
83631: kshiftrd/q Vk,Uk,Ib (66),(v)
83732: kshiftlb/w Vk,Uk,Ib (66),(v)
83833: kshiftld/q Vk,Uk,Ib (66),(v)
83938: vinserti128 Vqq,Hqq,Wqq,Ib (66),(v) | vinserti32x4/64x2 Vqq,Hqq,Wqq,Ib (66),(evo)
84039: vextracti128 Wdq,Vqq,Ib (66),(v) | vextracti32x4/64x2 Wdq,Vqq,Ib (66),(evo)
8413a: vinserti32x8/64x4 Vqq,Hqq,Wqq,Ib (66),(ev)
8423b: vextracti32x8/64x4 Wdq,Vqq,Ib (66),(ev)
8433e: vpcmpub/w Vk,Hk,Wx,Ib (66),(ev)
8443f: vpcmpb/w Vk,Hk,Wx,Ib (66),(ev)
79140: vdpps Vx,Hx,Wx,Ib (66) 84540: vdpps Vx,Hx,Wx,Ib (66)
79241: vdppd Vdq,Hdq,Wdq,Ib (66),(v1) 84641: vdppd Vdq,Hdq,Wdq,Ib (66),(v1)
79342: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) 84742: vmpsadbw Vx,Hx,Wx,Ib (66),(v1) | vdbpsadbw Vx,Hx,Wx,Ib (66),(evo)
84843: vshufi32x4/64x2 Vx,Hx,Wx,Ib (66),(ev)
79444: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1) 84944: vpclmulqdq Vdq,Hdq,Wdq,Ib (66),(v1)
79546: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v) 85046: vperm2i128 Vqq,Hqq,Wqq,Ib (66),(v)
7964a: vblendvps Vx,Hx,Wx,Lx (66),(v) 8514a: vblendvps Vx,Hx,Wx,Lx (66),(v)
7974b: vblendvpd Vx,Hx,Wx,Lx (66),(v) 8524b: vblendvpd Vx,Hx,Wx,Lx (66),(v)
7984c: vpblendvb Vx,Hx,Wx,Lx (66),(v1) 8534c: vpblendvb Vx,Hx,Wx,Lx (66),(v1)
85450: vrangeps/d Vx,Hx,Wx,Ib (66),(ev)
85551: vrangess/d Vx,Hx,Wx,Ib (66),(ev)
85654: vfixupimmps/d Vx,Hx,Wx,Ib (66),(ev)
85755: vfixupimmss/d Vx,Hx,Wx,Ib (66),(ev)
85856: vreduceps/d Vx,Wx,Ib (66),(ev)
85957: vreducess/d Vx,Hx,Wx,Ib (66),(ev)
79960: vpcmpestrm Vdq,Wdq,Ib (66),(v1) 86060: vpcmpestrm Vdq,Wdq,Ib (66),(v1)
80061: vpcmpestri Vdq,Wdq,Ib (66),(v1) 86161: vpcmpestri Vdq,Wdq,Ib (66),(v1)
80162: vpcmpistrm Vdq,Wdq,Ib (66),(v1) 86262: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
80263: vpcmpistri Vdq,Wdq,Ib (66),(v1) 86363: vpcmpistri Vdq,Wdq,Ib (66),(v1)
86466: vfpclassps/d Vk,Wx,Ib (66),(ev)
86567: vfpclassss/d Vk,Wx,Ib (66),(ev)
803cc: sha1rnds4 Vdq,Wdq,Ib 866cc: sha1rnds4 Vdq,Wdq,Ib
804df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) 867df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
805f0: RORX Gy,Ey,Ib (F2),(v) 868f0: RORX Gy,Ey,Ib (F2),(v)
@@ -927,8 +990,10 @@ GrpTable: Grp12
927EndTable 990EndTable
928 991
929GrpTable: Grp13 992GrpTable: Grp13
9930: vprord/q Hx,Wx,Ib (66),(ev)
9941: vprold/q Hx,Wx,Ib (66),(ev)
9302: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1) 9952: psrld Nq,Ib (11B) | vpsrld Hx,Ux,Ib (66),(11B),(v1)
9314: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) 9964: psrad Nq,Ib (11B) | vpsrad Hx,Ux,Ib (66),(11B),(v1) | vpsrad/q Hx,Ux,Ib (66),(evo)
9326: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1) 9976: pslld Nq,Ib (11B) | vpslld Hx,Ux,Ib (66),(11B),(v1)
933EndTable 998EndTable
934 999
@@ -947,7 +1012,7 @@ GrpTable: Grp15
9474: XSAVE 10124: XSAVE
9485: XRSTOR | lfence (11B) 10135: XRSTOR | lfence (11B)
9496: XSAVEOPT | clwb (66) | mfence (11B) 10146: XSAVEOPT | clwb (66) | mfence (11B)
9507: clflush | clflushopt (66) | sfence (11B) | pcommit (66),(11B) 10157: clflush | clflushopt (66) | sfence (11B)
951EndTable 1016EndTable
952 1017
953GrpTable: Grp16 1018GrpTable: Grp16
@@ -963,6 +1028,20 @@ GrpTable: Grp17
9633: BLSI By,Ey (v) 10283: BLSI By,Ey (v)
964EndTable 1029EndTable
965 1030
1031GrpTable: Grp18
10321: vgatherpf0dps/d Wx (66),(ev)
10332: vgatherpf1dps/d Wx (66),(ev)
10345: vscatterpf0dps/d Wx (66),(ev)
10356: vscatterpf1dps/d Wx (66),(ev)
1036EndTable
1037
1038GrpTable: Grp19
10391: vgatherpf0qps/d Wx (66),(ev)
10402: vgatherpf1qps/d Wx (66),(ev)
10415: vscatterpf0qps/d Wx (66),(ev)
10426: vscatterpf1qps/d Wx (66),(ev)
1043EndTable
1044
966# AMD's Prefetch Group 1045# AMD's Prefetch Group
967GrpTable: GrpP 1046GrpTable: GrpP
9680: PREFETCH 10470: PREFETCH
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 137196990012..551ff6f640be 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -39,6 +39,7 @@
39#include "auxtrace.h" 39#include "auxtrace.h"
40#include "tsc.h" 40#include "tsc.h"
41#include "intel-pt.h" 41#include "intel-pt.h"
42#include "config.h"
42 43
43#include "intel-pt-decoder/intel-pt-log.h" 44#include "intel-pt-decoder/intel-pt-log.h"
44#include "intel-pt-decoder/intel-pt-decoder.h" 45#include "intel-pt-decoder/intel-pt-decoder.h"
@@ -556,7 +557,7 @@ static bool intel_pt_exclude_kernel(struct intel_pt *pt)
556{ 557{
557 struct perf_evsel *evsel; 558 struct perf_evsel *evsel;
558 559
559 evlist__for_each(pt->session->evlist, evsel) { 560 evlist__for_each_entry(pt->session->evlist, evsel) {
560 if (intel_pt_get_config(pt, &evsel->attr, NULL) && 561 if (intel_pt_get_config(pt, &evsel->attr, NULL) &&
561 !evsel->attr.exclude_kernel) 562 !evsel->attr.exclude_kernel)
562 return false; 563 return false;
@@ -572,7 +573,7 @@ static bool intel_pt_return_compression(struct intel_pt *pt)
572 if (!pt->noretcomp_bit) 573 if (!pt->noretcomp_bit)
573 return true; 574 return true;
574 575
575 evlist__for_each(pt->session->evlist, evsel) { 576 evlist__for_each_entry(pt->session->evlist, evsel) {
576 if (intel_pt_get_config(pt, &evsel->attr, &config) && 577 if (intel_pt_get_config(pt, &evsel->attr, &config) &&
577 (config & pt->noretcomp_bit)) 578 (config & pt->noretcomp_bit))
578 return false; 579 return false;
@@ -592,7 +593,7 @@ static unsigned int intel_pt_mtc_period(struct intel_pt *pt)
592 for (shift = 0, config = pt->mtc_freq_bits; !(config & 1); shift++) 593 for (shift = 0, config = pt->mtc_freq_bits; !(config & 1); shift++)
593 config >>= 1; 594 config >>= 1;
594 595
595 evlist__for_each(pt->session->evlist, evsel) { 596 evlist__for_each_entry(pt->session->evlist, evsel) {
596 if (intel_pt_get_config(pt, &evsel->attr, &config)) 597 if (intel_pt_get_config(pt, &evsel->attr, &config))
597 return (config & pt->mtc_freq_bits) >> shift; 598 return (config & pt->mtc_freq_bits) >> shift;
598 } 599 }
@@ -608,7 +609,7 @@ static bool intel_pt_timeless_decoding(struct intel_pt *pt)
608 if (!pt->tsc_bit || !pt->cap_user_time_zero) 609 if (!pt->tsc_bit || !pt->cap_user_time_zero)
609 return true; 610 return true;
610 611
611 evlist__for_each(pt->session->evlist, evsel) { 612 evlist__for_each_entry(pt->session->evlist, evsel) {
612 if (!(evsel->attr.sample_type & PERF_SAMPLE_TIME)) 613 if (!(evsel->attr.sample_type & PERF_SAMPLE_TIME))
613 return true; 614 return true;
614 if (intel_pt_get_config(pt, &evsel->attr, &config)) { 615 if (intel_pt_get_config(pt, &evsel->attr, &config)) {
@@ -625,7 +626,7 @@ static bool intel_pt_tracing_kernel(struct intel_pt *pt)
625{ 626{
626 struct perf_evsel *evsel; 627 struct perf_evsel *evsel;
627 628
628 evlist__for_each(pt->session->evlist, evsel) { 629 evlist__for_each_entry(pt->session->evlist, evsel) {
629 if (intel_pt_get_config(pt, &evsel->attr, NULL) && 630 if (intel_pt_get_config(pt, &evsel->attr, NULL) &&
630 !evsel->attr.exclude_kernel) 631 !evsel->attr.exclude_kernel)
631 return true; 632 return true;
@@ -642,7 +643,7 @@ static bool intel_pt_have_tsc(struct intel_pt *pt)
642 if (!pt->tsc_bit) 643 if (!pt->tsc_bit)
643 return false; 644 return false;
644 645
645 evlist__for_each(pt->session->evlist, evsel) { 646 evlist__for_each_entry(pt->session->evlist, evsel) {
646 if (intel_pt_get_config(pt, &evsel->attr, &config)) { 647 if (intel_pt_get_config(pt, &evsel->attr, &config)) {
647 if (config & pt->tsc_bit) 648 if (config & pt->tsc_bit)
648 have_tsc = true; 649 have_tsc = true;
@@ -1233,7 +1234,7 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
1233 if (!(state->type & INTEL_PT_BRANCH)) 1234 if (!(state->type & INTEL_PT_BRANCH))
1234 return 0; 1235 return 0;
1235 1236
1236 if (pt->synth_opts.callchain) 1237 if (pt->synth_opts.callchain || pt->synth_opts.thread_stack)
1237 thread_stack__event(ptq->thread, ptq->flags, state->from_ip, 1238 thread_stack__event(ptq->thread, ptq->flags, state->from_ip,
1238 state->to_ip, ptq->insn_len, 1239 state->to_ip, ptq->insn_len,
1239 state->trace_nr); 1240 state->trace_nr);
@@ -1850,7 +1851,7 @@ static int intel_pt_synth_events(struct intel_pt *pt,
1850 u64 id; 1851 u64 id;
1851 int err; 1852 int err;
1852 1853
1853 evlist__for_each(evlist, evsel) { 1854 evlist__for_each_entry(evlist, evsel) {
1854 if (evsel->attr.type == pt->pmu_type && evsel->ids) { 1855 if (evsel->attr.type == pt->pmu_type && evsel->ids) {
1855 found = true; 1856 found = true;
1856 break; 1857 break;
@@ -1930,7 +1931,7 @@ static int intel_pt_synth_events(struct intel_pt *pt,
1930 pt->sample_transactions = true; 1931 pt->sample_transactions = true;
1931 pt->transactions_id = id; 1932 pt->transactions_id = id;
1932 id += 1; 1933 id += 1;
1933 evlist__for_each(evlist, evsel) { 1934 evlist__for_each_entry(evlist, evsel) {
1934 if (evsel->id && evsel->id[0] == pt->transactions_id) { 1935 if (evsel->id && evsel->id[0] == pt->transactions_id) {
1935 if (evsel->name) 1936 if (evsel->name)
1936 zfree(&evsel->name); 1937 zfree(&evsel->name);
@@ -1968,7 +1969,7 @@ static struct perf_evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist)
1968{ 1969{
1969 struct perf_evsel *evsel; 1970 struct perf_evsel *evsel;
1970 1971
1971 evlist__for_each_reverse(evlist, evsel) { 1972 evlist__for_each_entry_reverse(evlist, evsel) {
1972 const char *name = perf_evsel__name(evsel); 1973 const char *name = perf_evsel__name(evsel);
1973 1974
1974 if (!strcmp(name, "sched:sched_switch")) 1975 if (!strcmp(name, "sched:sched_switch"))
@@ -1982,7 +1983,7 @@ static bool intel_pt_find_switch(struct perf_evlist *evlist)
1982{ 1983{
1983 struct perf_evsel *evsel; 1984 struct perf_evsel *evsel;
1984 1985
1985 evlist__for_each(evlist, evsel) { 1986 evlist__for_each_entry(evlist, evsel) {
1986 if (evsel->attr.context_switch) 1987 if (evsel->attr.context_switch)
1987 return true; 1988 return true;
1988 } 1989 }
@@ -2136,6 +2137,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
2136 pt->synth_opts.branches = false; 2137 pt->synth_opts.branches = false;
2137 pt->synth_opts.callchain = true; 2138 pt->synth_opts.callchain = true;
2138 } 2139 }
2140 if (session->itrace_synth_opts)
2141 pt->synth_opts.thread_stack =
2142 session->itrace_synth_opts->thread_stack;
2139 } 2143 }
2140 2144
2141 if (pt->synth_opts.log) 2145 if (pt->synth_opts.log)
diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h
index aa6877d36858..020b9ca1b47e 100644
--- a/tools/perf/util/intlist.h
+++ b/tools/perf/util/intlist.h
@@ -57,21 +57,21 @@ static inline struct int_node *intlist__next(struct int_node *in)
57} 57}
58 58
59/** 59/**
60 * intlist_for_each - iterate over a intlist 60 * intlist__for_each_entry - iterate over a intlist
61 * @pos: the &struct int_node to use as a loop cursor. 61 * @pos: the &struct int_node to use as a loop cursor.
62 * @ilist: the &struct intlist for loop. 62 * @ilist: the &struct intlist for loop.
63 */ 63 */
64#define intlist__for_each(pos, ilist) \ 64#define intlist__for_each_entry(pos, ilist) \
65 for (pos = intlist__first(ilist); pos; pos = intlist__next(pos)) 65 for (pos = intlist__first(ilist); pos; pos = intlist__next(pos))
66 66
67/** 67/**
68 * intlist_for_each_safe - iterate over a intlist safe against removal of 68 * intlist__for_each_entry_safe - iterate over a intlist safe against removal of
69 * int_node 69 * int_node
70 * @pos: the &struct int_node to use as a loop cursor. 70 * @pos: the &struct int_node to use as a loop cursor.
71 * @n: another &struct int_node to use as temporary storage. 71 * @n: another &struct int_node to use as temporary storage.
72 * @ilist: the &struct intlist for loop. 72 * @ilist: the &struct intlist for loop.
73 */ 73 */
74#define intlist__for_each_safe(pos, n, ilist) \ 74#define intlist__for_each_entry_safe(pos, n, ilist) \
75 for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\ 75 for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\
76 pos = n, n = intlist__next(n)) 76 pos = n, n = intlist__next(n))
77#endif /* __PERF_INTLIST_H */ 77#endif /* __PERF_INTLIST_H */
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
index 86afe9618bb0..9f3305f6b6d5 100644
--- a/tools/perf/util/jitdump.c
+++ b/tools/perf/util/jitdump.c
@@ -108,7 +108,7 @@ jit_validate_events(struct perf_session *session)
108 /* 108 /*
109 * check that all events use CLOCK_MONOTONIC 109 * check that all events use CLOCK_MONOTONIC
110 */ 110 */
111 evlist__for_each(session->evlist, evsel) { 111 evlist__for_each_entry(session->evlist, evsel) {
112 if (evsel->attr.use_clockid == 0 || evsel->attr.clockid != CLOCK_MONOTONIC) 112 if (evsel->attr.use_clockid == 0 || evsel->attr.clockid != CLOCK_MONOTONIC)
113 return -1; 113 return -1;
114 } 114 }
diff --git a/tools/perf/util/levenshtein.c b/tools/perf/util/levenshtein.c
index e521d1516df6..f616e4f65b67 100644
--- a/tools/perf/util/levenshtein.c
+++ b/tools/perf/util/levenshtein.c
@@ -1,5 +1,7 @@
1#include "cache.h"
2#include "levenshtein.h" 1#include "levenshtein.h"
2#include <errno.h>
3#include <stdlib.h>
4#include <string.h>
3 5
4/* 6/*
5 * This function implements the Damerau-Levenshtein algorithm to 7 * This function implements the Damerau-Levenshtein algorithm to
diff --git a/tools/perf/util/libunwind/arm64.c b/tools/perf/util/libunwind/arm64.c
new file mode 100644
index 000000000000..6559bc586643
--- /dev/null
+++ b/tools/perf/util/libunwind/arm64.c
@@ -0,0 +1,40 @@
1/*
2 * This file setups defines to compile arch specific binary from the
3 * generic one.
4 *
5 * The function 'LIBUNWIND__ARCH_REG_ID' name is set according to arch
6 * name and the defination of this function is included directly from
7 * 'arch/arm64/util/unwind-libunwind.c', to make sure that this function
8 * is defined no matter what arch the host is.
9 *
10 * Finally, the arch specific unwind methods are exported which will
11 * be assigned to each arm64 thread.
12 */
13
14#define REMOTE_UNWIND_LIBUNWIND
15
16/* Define arch specific functions & regs for libunwind, should be
17 * defined before including "unwind.h"
18 */
19#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__arm64_reg_id(regnum)
20#define LIBUNWIND__ARCH_REG_IP PERF_REG_ARM64_PC
21#define LIBUNWIND__ARCH_REG_SP PERF_REG_ARM64_SP
22
23#include "unwind.h"
24#include "debug.h"
25#include "libunwind-aarch64.h"
26#include <../../../../arch/arm64/include/uapi/asm/perf_regs.h>
27#include "../../arch/arm64/util/unwind-libunwind.c"
28
29/* NO_LIBUNWIND_DEBUG_FRAME is a feature flag for local libunwind,
30 * assign NO_LIBUNWIND_DEBUG_FRAME_AARCH64 to it for compiling arm64
31 * unwind methods.
32 */
33#undef NO_LIBUNWIND_DEBUG_FRAME
34#ifdef NO_LIBUNWIND_DEBUG_FRAME_AARCH64
35#define NO_LIBUNWIND_DEBUG_FRAME
36#endif
37#include "util/unwind-libunwind-local.c"
38
39struct unwind_libunwind_ops *
40arm64_unwind_libunwind_ops = &_unwind_libunwind_ops;
diff --git a/tools/perf/util/libunwind/x86_32.c b/tools/perf/util/libunwind/x86_32.c
new file mode 100644
index 000000000000..957ffff72428
--- /dev/null
+++ b/tools/perf/util/libunwind/x86_32.c
@@ -0,0 +1,43 @@
1/*
2 * This file setups defines to compile arch specific binary from the
3 * generic one.
4 *
5 * The function 'LIBUNWIND__ARCH_REG_ID' name is set according to arch
6 * name and the defination of this function is included directly from
7 * 'arch/x86/util/unwind-libunwind.c', to make sure that this function
8 * is defined no matter what arch the host is.
9 *
10 * Finally, the arch specific unwind methods are exported which will
11 * be assigned to each x86 thread.
12 */
13
14#define REMOTE_UNWIND_LIBUNWIND
15
16/* Define arch specific functions & regs for libunwind, should be
17 * defined before including "unwind.h"
18 */
19#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__x86_reg_id(regnum)
20#define LIBUNWIND__ARCH_REG_IP PERF_REG_X86_IP
21#define LIBUNWIND__ARCH_REG_SP PERF_REG_X86_SP
22
23#include "unwind.h"
24#include "debug.h"
25#include "libunwind-x86.h"
26#include <../../../../arch/x86/include/uapi/asm/perf_regs.h>
27
28/* HAVE_ARCH_X86_64_SUPPORT is used in'arch/x86/util/unwind-libunwind.c'
29 * for x86_32, we undef it to compile code for x86_32 only.
30 */
31#undef HAVE_ARCH_X86_64_SUPPORT
32#include "../../arch/x86/util/unwind-libunwind.c"
33
34/* Explicitly define NO_LIBUNWIND_DEBUG_FRAME, because non-ARM has no
35 * dwarf_find_debug_frame() function.
36 */
37#ifndef NO_LIBUNWIND_DEBUG_FRAME
38#define NO_LIBUNWIND_DEBUG_FRAME
39#endif
40#include "util/unwind-libunwind-local.c"
41
42struct unwind_libunwind_ops *
43x86_32_unwind_libunwind_ops = &_unwind_libunwind_ops;
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 33071d6159bc..bf7216b8731d 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -3,11 +3,14 @@
3 * Copyright (C) 2015, Huawei Inc. 3 * Copyright (C) 2015, Huawei Inc.
4 */ 4 */
5 5
6#include <errno.h>
6#include <limits.h> 7#include <limits.h>
7#include <stdio.h> 8#include <stdio.h>
8#include <stdlib.h> 9#include <stdlib.h>
9#include "debug.h" 10#include "debug.h"
10#include "llvm-utils.h" 11#include "llvm-utils.h"
12#include "config.h"
13#include "util.h"
11 14
12#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \ 15#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \
13 "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\ 16 "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
@@ -42,6 +45,8 @@ int perf_llvm_config(const char *var, const char *value)
42 llvm_param.kbuild_dir = strdup(value); 45 llvm_param.kbuild_dir = strdup(value);
43 else if (!strcmp(var, "kbuild-opts")) 46 else if (!strcmp(var, "kbuild-opts"))
44 llvm_param.kbuild_opts = strdup(value); 47 llvm_param.kbuild_opts = strdup(value);
48 else if (!strcmp(var, "dump-obj"))
49 llvm_param.dump_obj = !!perf_config_bool(var, value);
45 else 50 else
46 return -1; 51 return -1;
47 llvm_param.user_set_param = true; 52 llvm_param.user_set_param = true;
@@ -103,7 +108,7 @@ read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
103 file = popen(cmd, "r"); 108 file = popen(cmd, "r");
104 if (!file) { 109 if (!file) {
105 pr_err("ERROR: unable to popen cmd: %s\n", 110 pr_err("ERROR: unable to popen cmd: %s\n",
106 strerror_r(errno, serr, sizeof(serr))); 111 str_error_r(errno, serr, sizeof(serr)));
107 return -EINVAL; 112 return -EINVAL;
108 } 113 }
109 114
@@ -137,7 +142,7 @@ read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
137 142
138 if (ferror(file)) { 143 if (ferror(file)) {
139 pr_err("ERROR: error occurred when reading from pipe: %s\n", 144 pr_err("ERROR: error occurred when reading from pipe: %s\n",
140 strerror_r(errno, serr, sizeof(serr))); 145 str_error_r(errno, serr, sizeof(serr)));
141 err = -EIO; 146 err = -EIO;
142 goto errout; 147 goto errout;
143 } 148 }
@@ -326,6 +331,42 @@ get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
326 pr_debug("include option is set to %s\n", *kbuild_include_opts); 331 pr_debug("include option is set to %s\n", *kbuild_include_opts);
327} 332}
328 333
334static void
335dump_obj(const char *path, void *obj_buf, size_t size)
336{
337 char *obj_path = strdup(path);
338 FILE *fp;
339 char *p;
340
341 if (!obj_path) {
342 pr_warning("WARNING: No enough memory, skip object dumping\n");
343 return;
344 }
345
346 p = strrchr(obj_path, '.');
347 if (!p || (strcmp(p, ".c") != 0)) {
348 pr_warning("WARNING: invalid llvm source path: '%s', skip object dumping\n",
349 obj_path);
350 goto out;
351 }
352
353 p[1] = 'o';
354 fp = fopen(obj_path, "wb");
355 if (!fp) {
356 pr_warning("WARNING: failed to open '%s': %s, skip object dumping\n",
357 obj_path, strerror(errno));
358 goto out;
359 }
360
361 pr_info("LLVM: dumping %s\n", obj_path);
362 if (fwrite(obj_buf, size, 1, fp) != 1)
363 pr_warning("WARNING: failed to write to file '%s': %s, skip object dumping\n",
364 obj_path, strerror(errno));
365 fclose(fp);
366out:
367 free(obj_path);
368}
369
329int llvm__compile_bpf(const char *path, void **p_obj_buf, 370int llvm__compile_bpf(const char *path, void **p_obj_buf,
330 size_t *p_obj_buf_sz) 371 size_t *p_obj_buf_sz)
331{ 372{
@@ -343,7 +384,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
343 if (path[0] != '-' && realpath(path, abspath) == NULL) { 384 if (path[0] != '-' && realpath(path, abspath) == NULL) {
344 err = errno; 385 err = errno;
345 pr_err("ERROR: problems with path %s: %s\n", 386 pr_err("ERROR: problems with path %s: %s\n",
346 path, strerror_r(err, serr, sizeof(serr))); 387 path, str_error_r(err, serr, sizeof(serr)));
347 return -err; 388 return -err;
348 } 389 }
349 390
@@ -371,7 +412,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
371 if (nr_cpus_avail <= 0) { 412 if (nr_cpus_avail <= 0) {
372 pr_err( 413 pr_err(
373"WARNING:\tunable to get available CPUs in this system: %s\n" 414"WARNING:\tunable to get available CPUs in this system: %s\n"
374" \tUse 128 instead.\n", strerror_r(errno, serr, sizeof(serr))); 415" \tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr)));
375 nr_cpus_avail = 128; 416 nr_cpus_avail = 128;
376 } 417 }
377 snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d", 418 snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
@@ -411,6 +452,10 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
411 452
412 free(kbuild_dir); 453 free(kbuild_dir);
413 free(kbuild_include_opts); 454 free(kbuild_include_opts);
455
456 if (llvm_param.dump_obj)
457 dump_obj(path, obj_buf, obj_buf_sz);
458
414 if (!p_obj_buf) 459 if (!p_obj_buf)
415 free(obj_buf); 460 free(obj_buf);
416 else 461 else
diff --git a/tools/perf/util/llvm-utils.h b/tools/perf/util/llvm-utils.h
index 23b9a743fe72..9f501cef06a1 100644
--- a/tools/perf/util/llvm-utils.h
+++ b/tools/perf/util/llvm-utils.h
@@ -30,6 +30,11 @@ struct llvm_param {
30 */ 30 */
31 const char *kbuild_opts; 31 const char *kbuild_opts;
32 /* 32 /*
33 * Default is false. If set to true, write compiling result
34 * to object file.
35 */
36 bool dump_obj;
37 /*
33 * Default is false. If one of the above fields is set by user 38 * Default is false. If one of the above fields is set by user
34 * explicitly then user_set_llvm is set to true. This is used 39 * explicitly then user_set_llvm is set to true. This is used
35 * for perf test. If user doesn't set anything in .perfconfig 40 * for perf test. If user doesn't set anything in .perfconfig
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index b1772180c820..cb6388dbdd98 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -138,8 +138,10 @@ void machine__exit(struct machine *machine)
138 138
139void machine__delete(struct machine *machine) 139void machine__delete(struct machine *machine)
140{ 140{
141 machine__exit(machine); 141 if (machine) {
142 free(machine); 142 machine__exit(machine);
143 free(machine);
144 }
143} 145}
144 146
145void machines__init(struct machines *machines) 147void machines__init(struct machines *machines)
@@ -1091,12 +1093,20 @@ static int machine__set_modules_path(struct machine *machine)
1091 1093
1092 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0); 1094 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0);
1093} 1095}
1096int __weak arch__fix_module_text_start(u64 *start __maybe_unused,
1097 const char *name __maybe_unused)
1098{
1099 return 0;
1100}
1094 1101
1095static int machine__create_module(void *arg, const char *name, u64 start) 1102static int machine__create_module(void *arg, const char *name, u64 start)
1096{ 1103{
1097 struct machine *machine = arg; 1104 struct machine *machine = arg;
1098 struct map *map; 1105 struct map *map;
1099 1106
1107 if (arch__fix_module_text_start(&start, name) < 0)
1108 return -1;
1109
1100 map = machine__findnew_module_map(machine, start, name); 1110 map = machine__findnew_module_map(machine, start, name);
1101 if (map == NULL) 1111 if (map == NULL)
1102 return -1; 1112 return -1;
@@ -1353,11 +1363,16 @@ int machine__process_mmap2_event(struct machine *machine,
1353 if (map == NULL) 1363 if (map == NULL)
1354 goto out_problem_map; 1364 goto out_problem_map;
1355 1365
1356 thread__insert_map(thread, map); 1366 ret = thread__insert_map(thread, map);
1367 if (ret)
1368 goto out_problem_insert;
1369
1357 thread__put(thread); 1370 thread__put(thread);
1358 map__put(map); 1371 map__put(map);
1359 return 0; 1372 return 0;
1360 1373
1374out_problem_insert:
1375 map__put(map);
1361out_problem_map: 1376out_problem_map:
1362 thread__put(thread); 1377 thread__put(thread);
1363out_problem: 1378out_problem:
@@ -1403,11 +1418,16 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
1403 if (map == NULL) 1418 if (map == NULL)
1404 goto out_problem_map; 1419 goto out_problem_map;
1405 1420
1406 thread__insert_map(thread, map); 1421 ret = thread__insert_map(thread, map);
1422 if (ret)
1423 goto out_problem_insert;
1424
1407 thread__put(thread); 1425 thread__put(thread);
1408 map__put(map); 1426 map__put(map);
1409 return 0; 1427 return 0;
1410 1428
1429out_problem_insert:
1430 map__put(map);
1411out_problem_map: 1431out_problem_map:
1412 thread__put(thread); 1432 thread__put(thread);
1413out_problem: 1433out_problem:
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 41ac9cfd416b..20739f746bc4 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -216,6 +216,7 @@ struct symbol *machine__find_kernel_function_by_name(struct machine *machine,
216 216
217struct map *machine__findnew_module_map(struct machine *machine, u64 start, 217struct map *machine__findnew_module_map(struct machine *machine, u64 start,
218 const char *filename); 218 const char *filename);
219int arch__fix_module_text_start(u64 *start, const char *name);
219 220
220int __machine__load_kallsyms(struct machine *machine, const char *filename, 221int __machine__load_kallsyms(struct machine *machine, const char *filename,
221 enum map_type type, bool no_kcore, symbol_filter_t filter); 222 enum map_type type, bool no_kcore, symbol_filter_t filter);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index b19bcd3b7128..728129ac653a 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -15,6 +15,7 @@
15#include "debug.h" 15#include "debug.h"
16#include "machine.h" 16#include "machine.h"
17#include <linux/string.h> 17#include <linux/string.h>
18#include "unwind.h"
18 19
19static void __maps__insert(struct maps *maps, struct map *map); 20static void __maps__insert(struct maps *maps, struct map *map);
20 21
@@ -311,6 +312,9 @@ int map__load(struct map *map, symbol_filter_t filter)
311 pr_warning("%.*s was updated (is prelink enabled?). " 312 pr_warning("%.*s was updated (is prelink enabled?). "
312 "Restart the long running apps that use it!\n", 313 "Restart the long running apps that use it!\n",
313 (int)real_len, name); 314 (int)real_len, name);
315 } else if (filter) {
316 pr_warning("no symbols passed the given filter.\n");
317 return -2; /* Empty but maybe by the filter */
314 } else { 318 } else {
315 pr_warning("no symbols found in %s, maybe install " 319 pr_warning("no symbols found in %s, maybe install "
316 "a debug package?\n", name); 320 "a debug package?\n", name);
@@ -744,9 +748,10 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
744/* 748/*
745 * XXX This should not really _copy_ te maps, but refcount them. 749 * XXX This should not really _copy_ te maps, but refcount them.
746 */ 750 */
747int map_groups__clone(struct map_groups *mg, 751int map_groups__clone(struct thread *thread,
748 struct map_groups *parent, enum map_type type) 752 struct map_groups *parent, enum map_type type)
749{ 753{
754 struct map_groups *mg = thread->mg;
750 int err = -ENOMEM; 755 int err = -ENOMEM;
751 struct map *map; 756 struct map *map;
752 struct maps *maps = &parent->maps[type]; 757 struct maps *maps = &parent->maps[type];
@@ -757,6 +762,11 @@ int map_groups__clone(struct map_groups *mg,
757 struct map *new = map__clone(map); 762 struct map *new = map__clone(map);
758 if (new == NULL) 763 if (new == NULL)
759 goto out_unlock; 764 goto out_unlock;
765
766 err = unwind__prepare_access(thread, new, NULL);
767 if (err)
768 goto out_unlock;
769
760 map_groups__insert(mg, new); 770 map_groups__insert(mg, new);
761 map__put(new); 771 map__put(new);
762 } 772 }
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 7309d64ce39e..d83396ceecba 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -194,7 +194,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
194 struct map **mapp, symbol_filter_t filter); 194 struct map **mapp, symbol_filter_t filter);
195void map_groups__init(struct map_groups *mg, struct machine *machine); 195void map_groups__init(struct map_groups *mg, struct machine *machine);
196void map_groups__exit(struct map_groups *mg); 196void map_groups__exit(struct map_groups *mg);
197int map_groups__clone(struct map_groups *mg, 197int map_groups__clone(struct thread *thread,
198 struct map_groups *parent, enum map_type type); 198 struct map_groups *parent, enum map_type type);
199size_t map_groups__fprintf(struct map_groups *mg, FILE *fp); 199size_t map_groups__fprintf(struct map_groups *mg, FILE *fp);
200 200
diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c
index 75465f89a413..bbc368e7d1e4 100644
--- a/tools/perf/util/mem-events.c
+++ b/tools/perf/util/mem-events.c
@@ -10,18 +10,33 @@
10#include "debug.h" 10#include "debug.h"
11#include "symbol.h" 11#include "symbol.h"
12 12
13unsigned int perf_mem_events__loads_ldlat = 30;
14
13#define E(t, n, s) { .tag = t, .name = n, .sysfs_name = s } 15#define E(t, n, s) { .tag = t, .name = n, .sysfs_name = s }
14 16
15struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = { 17struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = {
16 E("ldlat-loads", "cpu/mem-loads,ldlat=30/P", "mem-loads"), 18 E("ldlat-loads", "cpu/mem-loads,ldlat=%u/P", "mem-loads"),
17 E("ldlat-stores", "cpu/mem-stores/P", "mem-stores"), 19 E("ldlat-stores", "cpu/mem-stores/P", "mem-stores"),
18}; 20};
19#undef E 21#undef E
20 22
21#undef E 23#undef E
22 24
25static char mem_loads_name[100];
26static bool mem_loads_name__init;
27
23char *perf_mem_events__name(int i) 28char *perf_mem_events__name(int i)
24{ 29{
30 if (i == PERF_MEM_EVENTS__LOAD) {
31 if (!mem_loads_name__init) {
32 mem_loads_name__init = true;
33 scnprintf(mem_loads_name, sizeof(mem_loads_name),
34 perf_mem_events[i].name,
35 perf_mem_events__loads_ldlat);
36 }
37 return mem_loads_name;
38 }
39
25 return (char *)perf_mem_events[i].name; 40 return (char *)perf_mem_events[i].name;
26} 41}
27 42
diff --git a/tools/perf/util/mem-events.h b/tools/perf/util/mem-events.h
index 5d6d93066a6e..7f69bf9d789d 100644
--- a/tools/perf/util/mem-events.h
+++ b/tools/perf/util/mem-events.h
@@ -18,6 +18,7 @@ enum {
18}; 18};
19 19
20extern struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX]; 20extern struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX];
21extern unsigned int perf_mem_events__loads_ldlat;
21 22
22int perf_mem_events__parse(const char *str); 23int perf_mem_events__parse(const char *str);
23int perf_mem_events__init(void); 24int perf_mem_events__init(void);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index c6fd0479f4cd..6c913c3914fb 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -20,6 +20,7 @@
20#include "pmu.h" 20#include "pmu.h"
21#include "thread_map.h" 21#include "thread_map.h"
22#include "cpumap.h" 22#include "cpumap.h"
23#include "probe-file.h"
23#include "asm/bug.h" 24#include "asm/bug.h"
24 25
25#define MAX_NAME_LEN 100 26#define MAX_NAME_LEN 100
@@ -436,7 +437,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,
436} 437}
437 438
438static void tracepoint_error(struct parse_events_error *e, int err, 439static void tracepoint_error(struct parse_events_error *e, int err,
439 char *sys, char *name) 440 const char *sys, const char *name)
440{ 441{
441 char help[BUFSIZ]; 442 char help[BUFSIZ];
442 443
@@ -466,7 +467,7 @@ static void tracepoint_error(struct parse_events_error *e, int err,
466} 467}
467 468
468static int add_tracepoint(struct list_head *list, int *idx, 469static int add_tracepoint(struct list_head *list, int *idx,
469 char *sys_name, char *evt_name, 470 const char *sys_name, const char *evt_name,
470 struct parse_events_error *err, 471 struct parse_events_error *err,
471 struct list_head *head_config) 472 struct list_head *head_config)
472{ 473{
@@ -491,7 +492,7 @@ static int add_tracepoint(struct list_head *list, int *idx,
491} 492}
492 493
493static int add_tracepoint_multi_event(struct list_head *list, int *idx, 494static int add_tracepoint_multi_event(struct list_head *list, int *idx,
494 char *sys_name, char *evt_name, 495 const char *sys_name, const char *evt_name,
495 struct parse_events_error *err, 496 struct parse_events_error *err,
496 struct list_head *head_config) 497 struct list_head *head_config)
497{ 498{
@@ -533,7 +534,7 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
533} 534}
534 535
535static int add_tracepoint_event(struct list_head *list, int *idx, 536static int add_tracepoint_event(struct list_head *list, int *idx,
536 char *sys_name, char *evt_name, 537 const char *sys_name, const char *evt_name,
537 struct parse_events_error *err, 538 struct parse_events_error *err,
538 struct list_head *head_config) 539 struct list_head *head_config)
539{ 540{
@@ -545,7 +546,7 @@ static int add_tracepoint_event(struct list_head *list, int *idx,
545} 546}
546 547
547static int add_tracepoint_multi_sys(struct list_head *list, int *idx, 548static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
548 char *sys_name, char *evt_name, 549 const char *sys_name, const char *evt_name,
549 struct parse_events_error *err, 550 struct parse_events_error *err,
550 struct list_head *head_config) 551 struct list_head *head_config)
551{ 552{
@@ -584,7 +585,7 @@ struct __add_bpf_event_param {
584 struct list_head *head_config; 585 struct list_head *head_config;
585}; 586};
586 587
587static int add_bpf_event(struct probe_trace_event *tev, int fd, 588static int add_bpf_event(const char *group, const char *event, int fd,
588 void *_param) 589 void *_param)
589{ 590{
590 LIST_HEAD(new_evsels); 591 LIST_HEAD(new_evsels);
@@ -595,27 +596,27 @@ static int add_bpf_event(struct probe_trace_event *tev, int fd,
595 int err; 596 int err;
596 597
597 pr_debug("add bpf event %s:%s and attach bpf program %d\n", 598 pr_debug("add bpf event %s:%s and attach bpf program %d\n",
598 tev->group, tev->event, fd); 599 group, event, fd);
599 600
600 err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, tev->group, 601 err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, group,
601 tev->event, evlist->error, 602 event, evlist->error,
602 param->head_config); 603 param->head_config);
603 if (err) { 604 if (err) {
604 struct perf_evsel *evsel, *tmp; 605 struct perf_evsel *evsel, *tmp;
605 606
606 pr_debug("Failed to add BPF event %s:%s\n", 607 pr_debug("Failed to add BPF event %s:%s\n",
607 tev->group, tev->event); 608 group, event);
608 list_for_each_entry_safe(evsel, tmp, &new_evsels, node) { 609 list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
609 list_del(&evsel->node); 610 list_del(&evsel->node);
610 perf_evsel__delete(evsel); 611 perf_evsel__delete(evsel);
611 } 612 }
612 return err; 613 return err;
613 } 614 }
614 pr_debug("adding %s:%s\n", tev->group, tev->event); 615 pr_debug("adding %s:%s\n", group, event);
615 616
616 list_for_each_entry(pos, &new_evsels, node) { 617 list_for_each_entry(pos, &new_evsels, node) {
617 pr_debug("adding %s:%s to %p\n", 618 pr_debug("adding %s:%s to %p\n",
618 tev->group, tev->event, pos); 619 group, event, pos);
619 pos->bpf_fd = fd; 620 pos->bpf_fd = fd;
620 } 621 }
621 list_splice(&new_evsels, list); 622 list_splice(&new_evsels, list);
@@ -661,7 +662,7 @@ int parse_events_load_bpf_obj(struct parse_events_evlist *data,
661 goto errout; 662 goto errout;
662 } 663 }
663 664
664 err = bpf__foreach_tev(obj, add_bpf_event, &param); 665 err = bpf__foreach_event(obj, add_bpf_event, &param);
665 if (err) { 666 if (err) {
666 snprintf(errbuf, sizeof(errbuf), 667 snprintf(errbuf, sizeof(errbuf),
667 "Attach events in BPF object failed"); 668 "Attach events in BPF object failed");
@@ -900,6 +901,9 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
900 [PARSE_EVENTS__TERM_TYPE_STACKSIZE] = "stack-size", 901 [PARSE_EVENTS__TERM_TYPE_STACKSIZE] = "stack-size",
901 [PARSE_EVENTS__TERM_TYPE_NOINHERIT] = "no-inherit", 902 [PARSE_EVENTS__TERM_TYPE_NOINHERIT] = "no-inherit",
902 [PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit", 903 [PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit",
904 [PARSE_EVENTS__TERM_TYPE_MAX_STACK] = "max-stack",
905 [PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite",
906 [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
903}; 907};
904 908
905static bool config_term_shrinked; 909static bool config_term_shrinked;
@@ -992,9 +996,18 @@ do { \
992 case PARSE_EVENTS__TERM_TYPE_NOINHERIT: 996 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
993 CHECK_TYPE_VAL(NUM); 997 CHECK_TYPE_VAL(NUM);
994 break; 998 break;
999 case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
1000 CHECK_TYPE_VAL(NUM);
1001 break;
1002 case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
1003 CHECK_TYPE_VAL(NUM);
1004 break;
995 case PARSE_EVENTS__TERM_TYPE_NAME: 1005 case PARSE_EVENTS__TERM_TYPE_NAME:
996 CHECK_TYPE_VAL(STR); 1006 CHECK_TYPE_VAL(STR);
997 break; 1007 break;
1008 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
1009 CHECK_TYPE_VAL(NUM);
1010 break;
998 default: 1011 default:
999 err->str = strdup("unknown term"); 1012 err->str = strdup("unknown term");
1000 err->idx = term->err_term; 1013 err->idx = term->err_term;
@@ -1040,6 +1053,9 @@ static int config_term_tracepoint(struct perf_event_attr *attr,
1040 case PARSE_EVENTS__TERM_TYPE_STACKSIZE: 1053 case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
1041 case PARSE_EVENTS__TERM_TYPE_INHERIT: 1054 case PARSE_EVENTS__TERM_TYPE_INHERIT:
1042 case PARSE_EVENTS__TERM_TYPE_NOINHERIT: 1055 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
1056 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
1057 case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
1058 case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
1043 return config_term_common(attr, term, err); 1059 return config_term_common(attr, term, err);
1044 default: 1060 default:
1045 if (err) { 1061 if (err) {
@@ -1109,6 +1125,15 @@ do { \
1109 case PARSE_EVENTS__TERM_TYPE_NOINHERIT: 1125 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
1110 ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 0 : 1); 1126 ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 0 : 1);
1111 break; 1127 break;
1128 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
1129 ADD_CONFIG_TERM(MAX_STACK, max_stack, term->val.num);
1130 break;
1131 case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
1132 ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 1 : 0);
1133 break;
1134 case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
1135 ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1);
1136 break;
1112 default: 1137 default:
1113 break; 1138 break;
1114 } 1139 }
@@ -1118,7 +1143,7 @@ do { \
1118} 1143}
1119 1144
1120int parse_events_add_tracepoint(struct list_head *list, int *idx, 1145int parse_events_add_tracepoint(struct list_head *list, int *idx,
1121 char *sys, char *event, 1146 const char *sys, const char *event,
1122 struct parse_events_error *err, 1147 struct parse_events_error *err,
1123 struct list_head *head_config) 1148 struct list_head *head_config)
1124{ 1149{
@@ -1388,7 +1413,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
1388 if (!add && get_event_modifier(&mod, str, NULL)) 1413 if (!add && get_event_modifier(&mod, str, NULL))
1389 return -EINVAL; 1414 return -EINVAL;
1390 1415
1391 __evlist__for_each(list, evsel) { 1416 __evlist__for_each_entry(list, evsel) {
1392 if (add && get_event_modifier(&mod, str, evsel)) 1417 if (add && get_event_modifier(&mod, str, evsel))
1393 return -EINVAL; 1418 return -EINVAL;
1394 1419
@@ -1414,7 +1439,7 @@ int parse_events_name(struct list_head *list, char *name)
1414{ 1439{
1415 struct perf_evsel *evsel; 1440 struct perf_evsel *evsel;
1416 1441
1417 __evlist__for_each(list, evsel) { 1442 __evlist__for_each_entry(list, evsel) {
1418 if (!evsel->name) 1443 if (!evsel->name)
1419 evsel->name = strdup(name); 1444 evsel->name = strdup(name);
1420 } 1445 }
@@ -1976,6 +2001,85 @@ static bool is_event_supported(u8 type, unsigned config)
1976 return ret; 2001 return ret;
1977} 2002}
1978 2003
2004void print_sdt_events(const char *subsys_glob, const char *event_glob,
2005 bool name_only)
2006{
2007 struct probe_cache *pcache;
2008 struct probe_cache_entry *ent;
2009 struct strlist *bidlist, *sdtlist;
2010 struct strlist_config cfg = {.dont_dupstr = true};
2011 struct str_node *nd, *nd2;
2012 char *buf, *path, *ptr = NULL;
2013 bool show_detail = false;
2014 int ret;
2015
2016 sdtlist = strlist__new(NULL, &cfg);
2017 if (!sdtlist) {
2018 pr_debug("Failed to allocate new strlist for SDT\n");
2019 return;
2020 }
2021 bidlist = build_id_cache__list_all(true);
2022 if (!bidlist) {
2023 pr_debug("Failed to get buildids: %d\n", errno);
2024 return;
2025 }
2026 strlist__for_each_entry(nd, bidlist) {
2027 pcache = probe_cache__new(nd->s);
2028 if (!pcache)
2029 continue;
2030 list_for_each_entry(ent, &pcache->entries, node) {
2031 if (!ent->sdt)
2032 continue;
2033 if (subsys_glob &&
2034 !strglobmatch(ent->pev.group, subsys_glob))
2035 continue;
2036 if (event_glob &&
2037 !strglobmatch(ent->pev.event, event_glob))
2038 continue;
2039 ret = asprintf(&buf, "%s:%s@%s", ent->pev.group,
2040 ent->pev.event, nd->s);
2041 if (ret > 0)
2042 strlist__add(sdtlist, buf);
2043 }
2044 probe_cache__delete(pcache);
2045 }
2046 strlist__delete(bidlist);
2047
2048 strlist__for_each_entry(nd, sdtlist) {
2049 buf = strchr(nd->s, '@');
2050 if (buf)
2051 *(buf++) = '\0';
2052 if (name_only) {
2053 printf("%s ", nd->s);
2054 continue;
2055 }
2056 nd2 = strlist__next(nd);
2057 if (nd2) {
2058 ptr = strchr(nd2->s, '@');
2059 if (ptr)
2060 *ptr = '\0';
2061 if (strcmp(nd->s, nd2->s) == 0)
2062 show_detail = true;
2063 }
2064 if (show_detail) {
2065 path = build_id_cache__origname(buf);
2066 ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf);
2067 if (ret > 0) {
2068 printf(" %-50s [%s]\n", buf, "SDT event");
2069 free(buf);
2070 }
2071 } else
2072 printf(" %-50s [%s]\n", nd->s, "SDT event");
2073 if (nd2) {
2074 if (strcmp(nd->s, nd2->s) != 0)
2075 show_detail = false;
2076 if (ptr)
2077 *ptr = '@';
2078 }
2079 }
2080 strlist__delete(sdtlist);
2081}
2082
1979int print_hwcache_events(const char *event_glob, bool name_only) 2083int print_hwcache_events(const char *event_glob, bool name_only)
1980{ 2084{
1981 unsigned int type, op, i, evt_i = 0, evt_num = 0; 2085 unsigned int type, op, i, evt_i = 0, evt_num = 0;
@@ -2158,6 +2262,8 @@ void print_events(const char *event_glob, bool name_only)
2158 } 2262 }
2159 2263
2160 print_tracepoint_events(NULL, NULL, name_only); 2264 print_tracepoint_events(NULL, NULL, name_only);
2265
2266 print_sdt_events(NULL, NULL, name_only);
2161} 2267}
2162 2268
2163int parse_events__is_hardcoded_term(struct parse_events_term *term) 2269int parse_events__is_hardcoded_term(struct parse_events_term *term)
@@ -2322,9 +2428,9 @@ static void config_terms_list(char *buf, size_t buf_sz)
2322char *parse_events_formats_error_string(char *additional_terms) 2428char *parse_events_formats_error_string(char *additional_terms)
2323{ 2429{
2324 char *str; 2430 char *str;
2325 /* "branch_type" is the longest name */ 2431 /* "no-overwrite" is the longest name */
2326 char static_terms[__PARSE_EVENTS__TERM_TYPE_NR * 2432 char static_terms[__PARSE_EVENTS__TERM_TYPE_NR *
2327 (sizeof("branch_type") - 1)]; 2433 (sizeof("no-overwrite") - 1)];
2328 2434
2329 config_terms_list(static_terms, sizeof(static_terms)); 2435 config_terms_list(static_terms, sizeof(static_terms));
2330 /* valid terms */ 2436 /* valid terms */
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index d740c3ca9a1d..d1edbf8cc66a 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -68,6 +68,9 @@ enum {
68 PARSE_EVENTS__TERM_TYPE_STACKSIZE, 68 PARSE_EVENTS__TERM_TYPE_STACKSIZE,
69 PARSE_EVENTS__TERM_TYPE_NOINHERIT, 69 PARSE_EVENTS__TERM_TYPE_NOINHERIT,
70 PARSE_EVENTS__TERM_TYPE_INHERIT, 70 PARSE_EVENTS__TERM_TYPE_INHERIT,
71 PARSE_EVENTS__TERM_TYPE_MAX_STACK,
72 PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
73 PARSE_EVENTS__TERM_TYPE_OVERWRITE,
71 __PARSE_EVENTS__TERM_TYPE_NR, 74 __PARSE_EVENTS__TERM_TYPE_NR,
72}; 75};
73 76
@@ -133,7 +136,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add);
133int parse_events__modifier_group(struct list_head *list, char *event_mod); 136int parse_events__modifier_group(struct list_head *list, char *event_mod);
134int parse_events_name(struct list_head *list, char *name); 137int parse_events_name(struct list_head *list, char *name);
135int parse_events_add_tracepoint(struct list_head *list, int *idx, 138int parse_events_add_tracepoint(struct list_head *list, int *idx,
136 char *sys, char *event, 139 const char *sys, const char *event,
137 struct parse_events_error *error, 140 struct parse_events_error *error,
138 struct list_head *head_config); 141 struct list_head *head_config);
139int parse_events_load_bpf(struct parse_events_evlist *data, 142int parse_events_load_bpf(struct parse_events_evlist *data,
@@ -182,6 +185,8 @@ void print_symbol_events(const char *event_glob, unsigned type,
182void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 185void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
183 bool name_only); 186 bool name_only);
184int print_hwcache_events(const char *event_glob, bool name_only); 187int print_hwcache_events(const char *event_glob, bool name_only);
188void print_sdt_events(const char *subsys_glob, const char *event_glob,
189 bool name_only);
185int is_valid_tracepoint(const char *event_string); 190int is_valid_tracepoint(const char *event_string);
186 191
187int valid_event_mount(const char *eventfs); 192int valid_event_mount(const char *eventfs);
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 1477fbc78993..7a2519435da0 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -199,8 +199,11 @@ branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE
199time { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_TIME); } 199time { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_TIME); }
200call-graph { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CALLGRAPH); } 200call-graph { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CALLGRAPH); }
201stack-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_STACKSIZE); } 201stack-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_STACKSIZE); }
202max-stack { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_MAX_STACK); }
202inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); } 203inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
203no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); } 204no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
205overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); }
206no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
204, { return ','; } 207, { return ','; }
205"/" { BEGIN(INITIAL); return '/'; } 208"/" { BEGIN(INITIAL); return '/'; }
206{name_minus} { return str(yyscanner, PE_NAME); } 209{name_minus} { return str(yyscanner, PE_NAME); }
@@ -259,6 +262,7 @@ cycles-ct { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
259cycles-t { return str(yyscanner, PE_KERNEL_PMU_EVENT); } 262cycles-t { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
260mem-loads { return str(yyscanner, PE_KERNEL_PMU_EVENT); } 263mem-loads { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
261mem-stores { return str(yyscanner, PE_KERNEL_PMU_EVENT); } 264mem-stores { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
265topdown-[a-z-]+ { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
262 266
263L1-dcache|l1-d|l1d|L1-data | 267L1-dcache|l1-d|l1d|L1-data |
264L1-icache|l1-i|l1i|L1-instruction | 268L1-icache|l1-i|l1i|L1-instruction |
diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
index 3bf6bf82ff2d..7c7630be5a89 100644
--- a/tools/perf/util/path.c
+++ b/tools/perf/util/path.c
@@ -11,17 +11,13 @@
11 * which is what it's designed for. 11 * which is what it's designed for.
12 */ 12 */
13#include "cache.h" 13#include "cache.h"
14#include "util.h"
15#include <limits.h>
14 16
15static char bad_path[] = "/bad-path/"; 17static char bad_path[] = "/bad-path/";
16/* 18/*
17 * Two hacks: 19 * One hack:
18 */ 20 */
19
20static const char *get_perf_dir(void)
21{
22 return ".";
23}
24
25static char *get_pathname(void) 21static char *get_pathname(void)
26{ 22{
27 static char pathname_array[4][PATH_MAX]; 23 static char pathname_array[4][PATH_MAX];
@@ -54,60 +50,3 @@ char *mkpath(const char *fmt, ...)
54 return bad_path; 50 return bad_path;
55 return cleanup_path(pathname); 51 return cleanup_path(pathname);
56} 52}
57
58char *perf_path(const char *fmt, ...)
59{
60 const char *perf_dir = get_perf_dir();
61 char *pathname = get_pathname();
62 va_list args;
63 unsigned len;
64
65 len = strlen(perf_dir);
66 if (len > PATH_MAX-100)
67 return bad_path;
68 memcpy(pathname, perf_dir, len);
69 if (len && perf_dir[len-1] != '/')
70 pathname[len++] = '/';
71 va_start(args, fmt);
72 len += vsnprintf(pathname + len, PATH_MAX - len, fmt, args);
73 va_end(args);
74 if (len >= PATH_MAX)
75 return bad_path;
76 return cleanup_path(pathname);
77}
78
79/* strip arbitrary amount of directory separators at end of path */
80static inline int chomp_trailing_dir_sep(const char *path, int len)
81{
82 while (len && is_dir_sep(path[len - 1]))
83 len--;
84 return len;
85}
86
87/*
88 * If path ends with suffix (complete path components), returns the
89 * part before suffix (sans trailing directory separators).
90 * Otherwise returns NULL.
91 */
92char *strip_path_suffix(const char *path, const char *suffix)
93{
94 int path_len = strlen(path), suffix_len = strlen(suffix);
95
96 while (suffix_len) {
97 if (!path_len)
98 return NULL;
99
100 if (is_dir_sep(path[path_len - 1])) {
101 if (!is_dir_sep(suffix[suffix_len - 1]))
102 return NULL;
103 path_len = chomp_trailing_dir_sep(path, path_len);
104 suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
105 }
106 else if (path[--path_len] != suffix[--suffix_len])
107 return NULL;
108 }
109
110 if (path_len && !is_dir_sep(path[path_len - 1]))
111 return NULL;
112 return strndup(path, chomp_trailing_dir_sep(path, path_len));
113}
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 74401a20106d..953dc1ab2ed7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -67,7 +67,6 @@ int e_snprintf(char *str, size_t size, const char *format, ...)
67 return ret; 67 return ret;
68} 68}
69 69
70static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
71static struct machine *host_machine; 70static struct machine *host_machine;
72 71
73/* Initialize symbol maps and path of vmlinux/modules */ 72/* Initialize symbol maps and path of vmlinux/modules */
@@ -103,10 +102,8 @@ out:
103 102
104void exit_probe_symbol_maps(void) 103void exit_probe_symbol_maps(void)
105{ 104{
106 if (host_machine) { 105 machine__delete(host_machine);
107 machine__delete(host_machine); 106 host_machine = NULL;
108 host_machine = NULL;
109 }
110 symbol__exit(); 107 symbol__exit();
111} 108}
112 109
@@ -471,7 +468,7 @@ static struct debuginfo *open_debuginfo(const char *module, bool silent)
471 err = kernel_get_module_dso(module, &dso); 468 err = kernel_get_module_dso(module, &dso);
472 if (err < 0) { 469 if (err < 0) {
473 if (!dso || dso->load_errno == 0) { 470 if (!dso || dso->load_errno == 0) {
474 if (!strerror_r(-err, reason, STRERR_BUFSIZE)) 471 if (!str_error_r(-err, reason, STRERR_BUFSIZE))
475 strcpy(reason, "(unknown)"); 472 strcpy(reason, "(unknown)");
476 } else 473 } else
477 dso__strerror_load(dso, reason, STRERR_BUFSIZE); 474 dso__strerror_load(dso, reason, STRERR_BUFSIZE);
@@ -809,7 +806,7 @@ static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
809error: 806error:
810 if (ferror(fp)) { 807 if (ferror(fp)) {
811 pr_warning("File read error: %s\n", 808 pr_warning("File read error: %s\n",
812 strerror_r(errno, sbuf, sizeof(sbuf))); 809 str_error_r(errno, sbuf, sizeof(sbuf)));
813 return -1; 810 return -1;
814 } 811 }
815 return 0; 812 return 0;
@@ -889,7 +886,7 @@ static int __show_line_range(struct line_range *lr, const char *module,
889 fp = fopen(lr->path, "r"); 886 fp = fopen(lr->path, "r");
890 if (fp == NULL) { 887 if (fp == NULL) {
891 pr_warning("Failed to open %s: %s\n", lr->path, 888 pr_warning("Failed to open %s: %s\n", lr->path,
892 strerror_r(errno, sbuf, sizeof(sbuf))); 889 str_error_r(errno, sbuf, sizeof(sbuf)));
893 return -errno; 890 return -errno;
894 } 891 }
895 /* Skip to starting line number */ 892 /* Skip to starting line number */
@@ -899,7 +896,7 @@ static int __show_line_range(struct line_range *lr, const char *module,
899 goto end; 896 goto end;
900 } 897 }
901 898
902 intlist__for_each(ln, lr->line_list) { 899 intlist__for_each_entry(ln, lr->line_list) {
903 for (; ln->i > l; l++) { 900 for (; ln->i > l; l++) {
904 ret = show_one_line(fp, l - lr->offset); 901 ret = show_one_line(fp, l - lr->offset);
905 if (ret < 0) 902 if (ret < 0)
@@ -983,7 +980,7 @@ static int show_available_vars_at(struct debuginfo *dinfo,
983 zfree(&vl->point.symbol); 980 zfree(&vl->point.symbol);
984 nvars = 0; 981 nvars = 0;
985 if (vl->vars) { 982 if (vl->vars) {
986 strlist__for_each(node, vl->vars) { 983 strlist__for_each_entry(node, vl->vars) {
987 var = strchr(node->s, '\t') + 1; 984 var = strchr(node->s, '\t') + 1;
988 if (strfilter__compare(_filter, var)) { 985 if (strfilter__compare(_filter, var)) {
989 fprintf(stdout, "\t\t%s\n", node->s); 986 fprintf(stdout, "\t\t%s\n", node->s);
@@ -1200,6 +1197,34 @@ err:
1200 return err; 1197 return err;
1201} 1198}
1202 1199
1200static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
1201{
1202 char *ptr;
1203
1204 ptr = strchr(*arg, ':');
1205 if (ptr) {
1206 *ptr = '\0';
1207 if (!pev->sdt && !is_c_func_name(*arg))
1208 goto ng_name;
1209 pev->group = strdup(*arg);
1210 if (!pev->group)
1211 return -ENOMEM;
1212 *arg = ptr + 1;
1213 } else
1214 pev->group = NULL;
1215 if (!pev->sdt && !is_c_func_name(*arg)) {
1216ng_name:
1217 semantic_error("%s is bad for event name -it must "
1218 "follow C symbol-naming rule.\n", *arg);
1219 return -EINVAL;
1220 }
1221 pev->event = strdup(*arg);
1222 if (pev->event == NULL)
1223 return -ENOMEM;
1224
1225 return 0;
1226}
1227
1203/* Parse probepoint definition. */ 1228/* Parse probepoint definition. */
1204static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) 1229static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1205{ 1230{
@@ -1207,33 +1232,64 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1207 char *ptr, *tmp; 1232 char *ptr, *tmp;
1208 char c, nc = 0; 1233 char c, nc = 0;
1209 bool file_spec = false; 1234 bool file_spec = false;
1235 int ret;
1236
1210 /* 1237 /*
1211 * <Syntax> 1238 * <Syntax>
1212 * perf probe [EVENT=]SRC[:LN|;PTN] 1239 * perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
1213 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] 1240 * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
1214 * 1241 * perf probe %[GRP:]SDT_EVENT
1215 * TODO:Group name support
1216 */ 1242 */
1217 if (!arg) 1243 if (!arg)
1218 return -EINVAL; 1244 return -EINVAL;
1219 1245
1246 /*
1247 * If the probe point starts with '%',
1248 * or starts with "sdt_" and has a ':' but no '=',
1249 * then it should be a SDT/cached probe point.
1250 */
1251 if (arg[0] == '%' ||
1252 (!strncmp(arg, "sdt_", 4) &&
1253 !!strchr(arg, ':') && !strchr(arg, '='))) {
1254 pev->sdt = true;
1255 if (arg[0] == '%')
1256 arg++;
1257 }
1258
1220 ptr = strpbrk(arg, ";=@+%"); 1259 ptr = strpbrk(arg, ";=@+%");
1260 if (pev->sdt) {
1261 if (ptr) {
1262 if (*ptr != '@') {
1263 semantic_error("%s must be an SDT name.\n",
1264 arg);
1265 return -EINVAL;
1266 }
1267 /* This must be a target file name or build id */
1268 tmp = build_id_cache__complement(ptr + 1);
1269 if (tmp) {
1270 pev->target = build_id_cache__origname(tmp);
1271 free(tmp);
1272 } else
1273 pev->target = strdup(ptr + 1);
1274 if (!pev->target)
1275 return -ENOMEM;
1276 *ptr = '\0';
1277 }
1278 ret = parse_perf_probe_event_name(&arg, pev);
1279 if (ret == 0) {
1280 if (asprintf(&pev->point.function, "%%%s", pev->event) < 0)
1281 ret = -errno;
1282 }
1283 return ret;
1284 }
1285
1221 if (ptr && *ptr == '=') { /* Event name */ 1286 if (ptr && *ptr == '=') { /* Event name */
1222 *ptr = '\0'; 1287 *ptr = '\0';
1223 tmp = ptr + 1; 1288 tmp = ptr + 1;
1224 if (strchr(arg, ':')) { 1289 ret = parse_perf_probe_event_name(&arg, pev);
1225 semantic_error("Group name is not supported yet.\n"); 1290 if (ret < 0)
1226 return -ENOTSUP; 1291 return ret;
1227 } 1292
1228 if (!is_c_func_name(arg)) {
1229 semantic_error("%s is bad for event name -it must "
1230 "follow C symbol-naming rule.\n", arg);
1231 return -EINVAL;
1232 }
1233 pev->event = strdup(arg);
1234 if (pev->event == NULL)
1235 return -ENOMEM;
1236 pev->group = NULL;
1237 arg = tmp; 1293 arg = tmp;
1238 } 1294 }
1239 1295
@@ -1545,7 +1601,9 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
1545 return true; 1601 return true;
1546 1602
1547 for (i = 0; i < pev->nargs; i++) 1603 for (i = 0; i < pev->nargs; i++)
1548 if (is_c_varname(pev->args[i].var)) 1604 if (is_c_varname(pev->args[i].var) ||
1605 !strcmp(pev->args[i].var, "$params") ||
1606 !strcmp(pev->args[i].var, "$vars"))
1549 return true; 1607 return true;
1550 1608
1551 return false; 1609 return false;
@@ -1603,6 +1661,11 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
1603 p = strchr(argv[1], ':'); 1661 p = strchr(argv[1], ':');
1604 if (p) { 1662 if (p) {
1605 tp->module = strndup(argv[1], p - argv[1]); 1663 tp->module = strndup(argv[1], p - argv[1]);
1664 if (!tp->module) {
1665 ret = -ENOMEM;
1666 goto out;
1667 }
1668 tev->uprobes = (tp->module[0] == '/');
1606 p++; 1669 p++;
1607 } else 1670 } else
1608 p = argv[1]; 1671 p = argv[1];
@@ -1712,7 +1775,7 @@ out:
1712} 1775}
1713 1776
1714/* Compose only probe point (not argument) */ 1777/* Compose only probe point (not argument) */
1715static char *synthesize_perf_probe_point(struct perf_probe_point *pp) 1778char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1716{ 1779{
1717 struct strbuf buf; 1780 struct strbuf buf;
1718 char *tmp, *ret = NULL; 1781 char *tmp, *ret = NULL;
@@ -1751,30 +1814,36 @@ out:
1751 return ret; 1814 return ret;
1752} 1815}
1753 1816
1754#if 0
1755char *synthesize_perf_probe_command(struct perf_probe_event *pev) 1817char *synthesize_perf_probe_command(struct perf_probe_event *pev)
1756{ 1818{
1757 char *buf; 1819 struct strbuf buf;
1758 int i, len, ret; 1820 char *tmp, *ret = NULL;
1821 int i;
1759 1822
1760 buf = synthesize_perf_probe_point(&pev->point); 1823 if (strbuf_init(&buf, 64))
1761 if (!buf)
1762 return NULL; 1824 return NULL;
1825 if (pev->event)
1826 if (strbuf_addf(&buf, "%s:%s=", pev->group ?: PERFPROBE_GROUP,
1827 pev->event) < 0)
1828 goto out;
1829
1830 tmp = synthesize_perf_probe_point(&pev->point);
1831 if (!tmp || strbuf_addstr(&buf, tmp) < 0)
1832 goto out;
1833 free(tmp);
1763 1834
1764 len = strlen(buf);
1765 for (i = 0; i < pev->nargs; i++) { 1835 for (i = 0; i < pev->nargs; i++) {
1766 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 1836 tmp = synthesize_perf_probe_arg(pev->args + i);
1767 pev->args[i].name); 1837 if (!tmp || strbuf_addf(&buf, " %s", tmp) < 0)
1768 if (ret <= 0) { 1838 goto out;
1769 free(buf); 1839 free(tmp);
1770 return NULL;
1771 }
1772 len += ret;
1773 } 1840 }
1774 1841
1775 return buf; 1842 ret = strbuf_detach(&buf, NULL);
1843out:
1844 strbuf_release(&buf);
1845 return ret;
1776} 1846}
1777#endif
1778 1847
1779static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref, 1848static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
1780 struct strbuf *buf, int depth) 1849 struct strbuf *buf, int depth)
@@ -2026,6 +2095,79 @@ void clear_perf_probe_event(struct perf_probe_event *pev)
2026 memset(pev, 0, sizeof(*pev)); 2095 memset(pev, 0, sizeof(*pev));
2027} 2096}
2028 2097
2098#define strdup_or_goto(str, label) \
2099({ char *__p = NULL; if (str && !(__p = strdup(str))) goto label; __p; })
2100
2101static int perf_probe_point__copy(struct perf_probe_point *dst,
2102 struct perf_probe_point *src)
2103{
2104 dst->file = strdup_or_goto(src->file, out_err);
2105 dst->function = strdup_or_goto(src->function, out_err);
2106 dst->lazy_line = strdup_or_goto(src->lazy_line, out_err);
2107 dst->line = src->line;
2108 dst->retprobe = src->retprobe;
2109 dst->offset = src->offset;
2110 return 0;
2111
2112out_err:
2113 clear_perf_probe_point(dst);
2114 return -ENOMEM;
2115}
2116
2117static int perf_probe_arg__copy(struct perf_probe_arg *dst,
2118 struct perf_probe_arg *src)
2119{
2120 struct perf_probe_arg_field *field, **ppfield;
2121
2122 dst->name = strdup_or_goto(src->name, out_err);
2123 dst->var = strdup_or_goto(src->var, out_err);
2124 dst->type = strdup_or_goto(src->type, out_err);
2125
2126 field = src->field;
2127 ppfield = &(dst->field);
2128 while (field) {
2129 *ppfield = zalloc(sizeof(*field));
2130 if (!*ppfield)
2131 goto out_err;
2132 (*ppfield)->name = strdup_or_goto(field->name, out_err);
2133 (*ppfield)->index = field->index;
2134 (*ppfield)->ref = field->ref;
2135 field = field->next;
2136 ppfield = &((*ppfield)->next);
2137 }
2138 return 0;
2139out_err:
2140 return -ENOMEM;
2141}
2142
2143int perf_probe_event__copy(struct perf_probe_event *dst,
2144 struct perf_probe_event *src)
2145{
2146 int i;
2147
2148 dst->event = strdup_or_goto(src->event, out_err);
2149 dst->group = strdup_or_goto(src->group, out_err);
2150 dst->target = strdup_or_goto(src->target, out_err);
2151 dst->uprobes = src->uprobes;
2152
2153 if (perf_probe_point__copy(&dst->point, &src->point) < 0)
2154 goto out_err;
2155
2156 dst->args = zalloc(sizeof(struct perf_probe_arg) * src->nargs);
2157 if (!dst->args)
2158 goto out_err;
2159 dst->nargs = src->nargs;
2160
2161 for (i = 0; i < src->nargs; i++)
2162 if (perf_probe_arg__copy(&dst->args[i], &src->args[i]) < 0)
2163 goto out_err;
2164 return 0;
2165
2166out_err:
2167 clear_perf_probe_event(dst);
2168 return -ENOMEM;
2169}
2170
2029void clear_probe_trace_event(struct probe_trace_event *tev) 2171void clear_probe_trace_event(struct probe_trace_event *tev)
2030{ 2172{
2031 struct probe_trace_arg_ref *ref, *next; 2173 struct probe_trace_arg_ref *ref, *next;
@@ -2253,7 +2395,7 @@ static int __show_perf_probe_events(int fd, bool is_kprobe,
2253 if (!rawlist) 2395 if (!rawlist)
2254 return -ENOMEM; 2396 return -ENOMEM;
2255 2397
2256 strlist__for_each(ent, rawlist) { 2398 strlist__for_each_entry(ent, rawlist) {
2257 ret = parse_probe_trace_command(ent->s, &tev); 2399 ret = parse_probe_trace_command(ent->s, &tev);
2258 if (ret >= 0) { 2400 if (ret >= 0) {
2259 if (!filter_probe_trace_event(&tev, filter)) 2401 if (!filter_probe_trace_event(&tev, filter))
@@ -2286,6 +2428,9 @@ int show_perf_probe_events(struct strfilter *filter)
2286 2428
2287 setup_pager(); 2429 setup_pager();
2288 2430
2431 if (probe_conf.cache)
2432 return probe_cache__show_all_caches(filter);
2433
2289 ret = init_probe_symbol_maps(false); 2434 ret = init_probe_symbol_maps(false);
2290 if (ret < 0) 2435 if (ret < 0)
2291 return ret; 2436 return ret;
@@ -2394,17 +2539,24 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
2394 char buf[64]; 2539 char buf[64];
2395 int ret; 2540 int ret;
2396 2541
2397 if (pev->event) 2542 /* If probe_event or trace_event already have the name, reuse it */
2543 if (pev->event && !pev->sdt)
2398 event = pev->event; 2544 event = pev->event;
2399 else 2545 else if (tev->event)
2546 event = tev->event;
2547 else {
2548 /* Or generate new one from probe point */
2400 if (pev->point.function && 2549 if (pev->point.function &&
2401 (strncmp(pev->point.function, "0x", 2) != 0) && 2550 (strncmp(pev->point.function, "0x", 2) != 0) &&
2402 !strisglob(pev->point.function)) 2551 !strisglob(pev->point.function))
2403 event = pev->point.function; 2552 event = pev->point.function;
2404 else 2553 else
2405 event = tev->point.realname; 2554 event = tev->point.realname;
2406 if (pev->group) 2555 }
2556 if (pev->group && !pev->sdt)
2407 group = pev->group; 2557 group = pev->group;
2558 else if (tev->group)
2559 group = tev->group;
2408 else 2560 else
2409 group = PERFPROBE_GROUP; 2561 group = PERFPROBE_GROUP;
2410 2562
@@ -2426,40 +2578,60 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
2426 return 0; 2578 return 0;
2427} 2579}
2428 2580
2429static int __add_probe_trace_events(struct perf_probe_event *pev, 2581static int __open_probe_file_and_namelist(bool uprobe,
2430 struct probe_trace_event *tevs, 2582 struct strlist **namelist)
2431 int ntevs, bool allow_suffix)
2432{ 2583{
2433 int i, fd, ret; 2584 int fd;
2434 struct probe_trace_event *tev = NULL;
2435 struct strlist *namelist;
2436 2585
2437 fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0)); 2586 fd = probe_file__open(PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0));
2438 if (fd < 0) 2587 if (fd < 0)
2439 return fd; 2588 return fd;
2440 2589
2441 /* Get current event names */ 2590 /* Get current event names */
2442 namelist = probe_file__get_namelist(fd); 2591 *namelist = probe_file__get_namelist(fd);
2443 if (!namelist) { 2592 if (!(*namelist)) {
2444 pr_debug("Failed to get current event list.\n"); 2593 pr_debug("Failed to get current event list.\n");
2445 ret = -ENOMEM; 2594 close(fd);
2446 goto close_out; 2595 return -ENOMEM;
2447 } 2596 }
2597 return fd;
2598}
2599
2600static int __add_probe_trace_events(struct perf_probe_event *pev,
2601 struct probe_trace_event *tevs,
2602 int ntevs, bool allow_suffix)
2603{
2604 int i, fd[2] = {-1, -1}, up, ret;
2605 struct probe_trace_event *tev = NULL;
2606 struct probe_cache *cache = NULL;
2607 struct strlist *namelist[2] = {NULL, NULL};
2608
2609 up = pev->uprobes ? 1 : 0;
2610 fd[up] = __open_probe_file_and_namelist(up, &namelist[up]);
2611 if (fd[up] < 0)
2612 return fd[up];
2448 2613
2449 ret = 0; 2614 ret = 0;
2450 for (i = 0; i < ntevs; i++) { 2615 for (i = 0; i < ntevs; i++) {
2451 tev = &tevs[i]; 2616 tev = &tevs[i];
2617 up = tev->uprobes ? 1 : 0;
2618 if (fd[up] == -1) { /* Open the kprobe/uprobe_events */
2619 fd[up] = __open_probe_file_and_namelist(up,
2620 &namelist[up]);
2621 if (fd[up] < 0)
2622 goto close_out;
2623 }
2452 /* Skip if the symbol is out of .text or blacklisted */ 2624 /* Skip if the symbol is out of .text or blacklisted */
2453 if (!tev->point.symbol) 2625 if (!tev->point.symbol && !pev->uprobes)
2454 continue; 2626 continue;
2455 2627
2456 /* Set new name for tev (and update namelist) */ 2628 /* Set new name for tev (and update namelist) */
2457 ret = probe_trace_event__set_name(tev, pev, namelist, 2629 ret = probe_trace_event__set_name(tev, pev, namelist[up],
2458 allow_suffix); 2630 allow_suffix);
2459 if (ret < 0) 2631 if (ret < 0)
2460 break; 2632 break;
2461 2633
2462 ret = probe_file__add_event(fd, tev); 2634 ret = probe_file__add_event(fd[up], tev);
2463 if (ret < 0) 2635 if (ret < 0)
2464 break; 2636 break;
2465 2637
@@ -2473,10 +2645,21 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
2473 } 2645 }
2474 if (ret == -EINVAL && pev->uprobes) 2646 if (ret == -EINVAL && pev->uprobes)
2475 warn_uprobe_event_compat(tev); 2647 warn_uprobe_event_compat(tev);
2648 if (ret == 0 && probe_conf.cache) {
2649 cache = probe_cache__new(pev->target);
2650 if (!cache ||
2651 probe_cache__add_entry(cache, pev, tevs, ntevs) < 0 ||
2652 probe_cache__commit(cache) < 0)
2653 pr_warning("Failed to add event to probe cache\n");
2654 probe_cache__delete(cache);
2655 }
2476 2656
2477 strlist__delete(namelist);
2478close_out: 2657close_out:
2479 close(fd); 2658 for (up = 0; up < 2; up++) {
2659 strlist__delete(namelist[up]);
2660 if (fd[up] >= 0)
2661 close(fd[up]);
2662 }
2480 return ret; 2663 return ret;
2481} 2664}
2482 2665
@@ -2501,9 +2684,6 @@ static int find_probe_functions(struct map *map, char *name,
2501 return found; 2684 return found;
2502} 2685}
2503 2686
2504#define strdup_or_goto(str, label) \
2505 ({ char *__p = strdup(str); if (!__p) goto label; __p; })
2506
2507void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused, 2687void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
2508 struct probe_trace_event *tev __maybe_unused, 2688 struct probe_trace_event *tev __maybe_unused,
2509 struct map *map __maybe_unused, 2689 struct map *map __maybe_unused,
@@ -2758,12 +2938,205 @@ errout:
2758 2938
2759bool __weak arch__prefers_symtab(void) { return false; } 2939bool __weak arch__prefers_symtab(void) { return false; }
2760 2940
2941/* Concatinate two arrays */
2942static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
2943{
2944 void *ret;
2945
2946 ret = malloc(sz_a + sz_b);
2947 if (ret) {
2948 memcpy(ret, a, sz_a);
2949 memcpy(ret + sz_a, b, sz_b);
2950 }
2951 return ret;
2952}
2953
2954static int
2955concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
2956 struct probe_trace_event **tevs2, int ntevs2)
2957{
2958 struct probe_trace_event *new_tevs;
2959 int ret = 0;
2960
2961 if (ntevs == 0) {
2962 *tevs = *tevs2;
2963 *ntevs = ntevs2;
2964 *tevs2 = NULL;
2965 return 0;
2966 }
2967
2968 if (*ntevs + ntevs2 > probe_conf.max_probes)
2969 ret = -E2BIG;
2970 else {
2971 /* Concatinate the array of probe_trace_event */
2972 new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
2973 *tevs2, ntevs2 * sizeof(**tevs2));
2974 if (!new_tevs)
2975 ret = -ENOMEM;
2976 else {
2977 free(*tevs);
2978 *tevs = new_tevs;
2979 *ntevs += ntevs2;
2980 }
2981 }
2982 if (ret < 0)
2983 clear_probe_trace_events(*tevs2, ntevs2);
2984 zfree(tevs2);
2985
2986 return ret;
2987}
2988
2989/*
2990 * Try to find probe_trace_event from given probe caches. Return the number
2991 * of cached events found, if an error occurs return the error.
2992 */
2993static int find_cached_events(struct perf_probe_event *pev,
2994 struct probe_trace_event **tevs,
2995 const char *target)
2996{
2997 struct probe_cache *cache;
2998 struct probe_cache_entry *entry;
2999 struct probe_trace_event *tmp_tevs = NULL;
3000 int ntevs = 0;
3001 int ret = 0;
3002
3003 cache = probe_cache__new(target);
3004 /* Return 0 ("not found") if the target has no probe cache. */
3005 if (!cache)
3006 return 0;
3007
3008 for_each_probe_cache_entry(entry, cache) {
3009 /* Skip the cache entry which has no name */
3010 if (!entry->pev.event || !entry->pev.group)
3011 continue;
3012 if ((!pev->group || strglobmatch(entry->pev.group, pev->group)) &&
3013 strglobmatch(entry->pev.event, pev->event)) {
3014 ret = probe_cache_entry__get_event(entry, &tmp_tevs);
3015 if (ret > 0)
3016 ret = concat_probe_trace_events(tevs, &ntevs,
3017 &tmp_tevs, ret);
3018 if (ret < 0)
3019 break;
3020 }
3021 }
3022 probe_cache__delete(cache);
3023 if (ret < 0) {
3024 clear_probe_trace_events(*tevs, ntevs);
3025 zfree(tevs);
3026 } else {
3027 ret = ntevs;
3028 if (ntevs > 0 && target && target[0] == '/')
3029 pev->uprobes = true;
3030 }
3031
3032 return ret;
3033}
3034
3035/* Try to find probe_trace_event from all probe caches */
3036static int find_cached_events_all(struct perf_probe_event *pev,
3037 struct probe_trace_event **tevs)
3038{
3039 struct probe_trace_event *tmp_tevs = NULL;
3040 struct strlist *bidlist;
3041 struct str_node *nd;
3042 char *pathname;
3043 int ntevs = 0;
3044 int ret;
3045
3046 /* Get the buildid list of all valid caches */
3047 bidlist = build_id_cache__list_all(true);
3048 if (!bidlist) {
3049 ret = -errno;
3050 pr_debug("Failed to get buildids: %d\n", ret);
3051 return ret;
3052 }
3053
3054 ret = 0;
3055 strlist__for_each_entry(nd, bidlist) {
3056 pathname = build_id_cache__origname(nd->s);
3057 ret = find_cached_events(pev, &tmp_tevs, pathname);
3058 /* In the case of cnt == 0, we just skip it */
3059 if (ret > 0)
3060 ret = concat_probe_trace_events(tevs, &ntevs,
3061 &tmp_tevs, ret);
3062 free(pathname);
3063 if (ret < 0)
3064 break;
3065 }
3066 strlist__delete(bidlist);
3067
3068 if (ret < 0) {
3069 clear_probe_trace_events(*tevs, ntevs);
3070 zfree(tevs);
3071 } else
3072 ret = ntevs;
3073
3074 return ret;
3075}
3076
3077static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
3078 struct probe_trace_event **tevs)
3079{
3080 struct probe_cache *cache;
3081 struct probe_cache_entry *entry;
3082 struct probe_trace_event *tev;
3083 struct str_node *node;
3084 int ret, i;
3085
3086 if (pev->sdt) {
3087 /* For SDT/cached events, we use special search functions */
3088 if (!pev->target)
3089 return find_cached_events_all(pev, tevs);
3090 else
3091 return find_cached_events(pev, tevs, pev->target);
3092 }
3093 cache = probe_cache__new(pev->target);
3094 if (!cache)
3095 return 0;
3096
3097 entry = probe_cache__find(cache, pev);
3098 if (!entry) {
3099 /* SDT must be in the cache */
3100 ret = pev->sdt ? -ENOENT : 0;
3101 goto out;
3102 }
3103
3104 ret = strlist__nr_entries(entry->tevlist);
3105 if (ret > probe_conf.max_probes) {
3106 pr_debug("Too many entries matched in the cache of %s\n",
3107 pev->target ? : "kernel");
3108 ret = -E2BIG;
3109 goto out;
3110 }
3111
3112 *tevs = zalloc(ret * sizeof(*tev));
3113 if (!*tevs) {
3114 ret = -ENOMEM;
3115 goto out;
3116 }
3117
3118 i = 0;
3119 strlist__for_each_entry(node, entry->tevlist) {
3120 tev = &(*tevs)[i++];
3121 ret = parse_probe_trace_command(node->s, tev);
3122 if (ret < 0)
3123 goto out;
3124 /* Set the uprobes attribute as same as original */
3125 tev->uprobes = pev->uprobes;
3126 }
3127 ret = i;
3128
3129out:
3130 probe_cache__delete(cache);
3131 return ret;
3132}
3133
2761static int convert_to_probe_trace_events(struct perf_probe_event *pev, 3134static int convert_to_probe_trace_events(struct perf_probe_event *pev,
2762 struct probe_trace_event **tevs) 3135 struct probe_trace_event **tevs)
2763{ 3136{
2764 int ret; 3137 int ret;
2765 3138
2766 if (!pev->group) { 3139 if (!pev->group && !pev->sdt) {
2767 /* Set group name if not given */ 3140 /* Set group name if not given */
2768 if (!pev->uprobes) { 3141 if (!pev->uprobes) {
2769 pev->group = strdup(PERFPROBE_GROUP); 3142 pev->group = strdup(PERFPROBE_GROUP);
@@ -2780,6 +3153,11 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
2780 if (ret > 0) 3153 if (ret > 0)
2781 return ret; 3154 return ret;
2782 3155
3156 /* At first, we need to lookup cache entry */
3157 ret = find_probe_trace_events_from_cache(pev, tevs);
3158 if (ret > 0 || pev->sdt) /* SDT can be found only in the cache */
3159 return ret == 0 ? -ENOENT : ret; /* Found in probe cache */
3160
2783 if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) { 3161 if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
2784 ret = find_probe_trace_events_from_map(pev, tevs); 3162 ret = find_probe_trace_events_from_map(pev, tevs);
2785 if (ret > 0) 3163 if (ret > 0)
@@ -2934,8 +3312,16 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
2934 3312
2935 /* Load symbols with given filter */ 3313 /* Load symbols with given filter */
2936 available_func_filter = _filter; 3314 available_func_filter = _filter;
2937 if (map__load(map, filter_available_functions)) { 3315 ret = map__load(map, filter_available_functions);
2938 pr_err("Failed to load symbols in %s\n", (target) ? : "kernel"); 3316 if (ret) {
3317 if (ret == -2) {
3318 char *str = strfilter__string(_filter);
3319 pr_err("Failed to find symbols matched to \"%s\"\n",
3320 str);
3321 free(str);
3322 } else
3323 pr_err("Failed to load symbols in %s\n",
3324 (target) ? : "kernel");
2939 goto end; 3325 goto end;
2940 } 3326 }
2941 if (!dso__sorted_by_name(map->dso, map->type)) 3327 if (!dso__sorted_by_name(map->dso, map->type))
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 5a27eb4fad05..e18ea9fe6385 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -12,6 +12,7 @@ struct probe_conf {
12 bool show_location_range; 12 bool show_location_range;
13 bool force_add; 13 bool force_add;
14 bool no_inlines; 14 bool no_inlines;
15 bool cache;
15 int max_probes; 16 int max_probes;
16}; 17};
17extern struct probe_conf probe_conf; 18extern struct probe_conf probe_conf;
@@ -84,6 +85,7 @@ struct perf_probe_event {
84 char *group; /* Group name */ 85 char *group; /* Group name */
85 struct perf_probe_point point; /* Probe point */ 86 struct perf_probe_point point; /* Probe point */
86 int nargs; /* Number of arguments */ 87 int nargs; /* Number of arguments */
88 bool sdt; /* SDT/cached event flag */
87 bool uprobes; /* Uprobe event flag */ 89 bool uprobes; /* Uprobe event flag */
88 char *target; /* Target binary */ 90 char *target; /* Target binary */
89 struct perf_probe_arg *args; /* Arguments */ 91 struct perf_probe_arg *args; /* Arguments */
@@ -121,6 +123,10 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev);
121char *synthesize_perf_probe_command(struct perf_probe_event *pev); 123char *synthesize_perf_probe_command(struct perf_probe_event *pev);
122char *synthesize_probe_trace_command(struct probe_trace_event *tev); 124char *synthesize_probe_trace_command(struct probe_trace_event *tev);
123char *synthesize_perf_probe_arg(struct perf_probe_arg *pa); 125char *synthesize_perf_probe_arg(struct perf_probe_arg *pa);
126char *synthesize_perf_probe_point(struct perf_probe_point *pp);
127
128int perf_probe_event__copy(struct perf_probe_event *dst,
129 struct perf_probe_event *src);
124 130
125/* Check the perf_probe_event needs debuginfo */ 131/* Check the perf_probe_event needs debuginfo */
126bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); 132bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 3fe6214970e6..9aed9c332da6 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -14,6 +14,7 @@
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 */ 16 */
17#include <sys/uio.h>
17#include "util.h" 18#include "util.h"
18#include "event.h" 19#include "event.h"
19#include "strlist.h" 20#include "strlist.h"
@@ -49,7 +50,7 @@ static void print_open_warning(int err, bool uprobe)
49 else 50 else
50 pr_warning("Failed to open %cprobe_events: %s\n", 51 pr_warning("Failed to open %cprobe_events: %s\n",
51 uprobe ? 'u' : 'k', 52 uprobe ? 'u' : 'k',
52 strerror_r(-err, sbuf, sizeof(sbuf))); 53 str_error_r(-err, sbuf, sizeof(sbuf)));
53} 54}
54 55
55static void print_both_open_warning(int kerr, int uerr) 56static void print_both_open_warning(int kerr, int uerr)
@@ -63,9 +64,9 @@ static void print_both_open_warning(int kerr, int uerr)
63 else { 64 else {
64 char sbuf[STRERR_BUFSIZE]; 65 char sbuf[STRERR_BUFSIZE];
65 pr_warning("Failed to open kprobe events: %s.\n", 66 pr_warning("Failed to open kprobe events: %s.\n",
66 strerror_r(-kerr, sbuf, sizeof(sbuf))); 67 str_error_r(-kerr, sbuf, sizeof(sbuf)));
67 pr_warning("Failed to open uprobe events: %s.\n", 68 pr_warning("Failed to open uprobe events: %s.\n",
68 strerror_r(-uerr, sbuf, sizeof(sbuf))); 69 str_error_r(-uerr, sbuf, sizeof(sbuf)));
69 } 70 }
70} 71}
71 72
@@ -177,7 +178,7 @@ static struct strlist *__probe_file__get_namelist(int fd, bool include_group)
177 if (!rawlist) 178 if (!rawlist)
178 return NULL; 179 return NULL;
179 sl = strlist__new(NULL, NULL); 180 sl = strlist__new(NULL, NULL);
180 strlist__for_each(ent, rawlist) { 181 strlist__for_each_entry(ent, rawlist) {
181 ret = parse_probe_trace_command(ent->s, &tev); 182 ret = parse_probe_trace_command(ent->s, &tev);
182 if (ret < 0) 183 if (ret < 0)
183 break; 184 break;
@@ -223,7 +224,7 @@ int probe_file__add_event(int fd, struct probe_trace_event *tev)
223 if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) { 224 if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) {
224 ret = -errno; 225 ret = -errno;
225 pr_warning("Failed to write event: %s\n", 226 pr_warning("Failed to write event: %s\n",
226 strerror_r(errno, sbuf, sizeof(sbuf))); 227 str_error_r(errno, sbuf, sizeof(sbuf)));
227 } 228 }
228 } 229 }
229 free(buf); 230 free(buf);
@@ -261,7 +262,7 @@ static int __del_trace_probe_event(int fd, struct str_node *ent)
261 return 0; 262 return 0;
262error: 263error:
263 pr_warning("Failed to delete event: %s\n", 264 pr_warning("Failed to delete event: %s\n",
264 strerror_r(-ret, buf, sizeof(buf))); 265 str_error_r(-ret, buf, sizeof(buf)));
265 return ret; 266 return ret;
266} 267}
267 268
@@ -280,7 +281,7 @@ int probe_file__get_events(int fd, struct strfilter *filter,
280 if (!namelist) 281 if (!namelist)
281 return -ENOENT; 282 return -ENOENT;
282 283
283 strlist__for_each(ent, namelist) { 284 strlist__for_each_entry(ent, namelist) {
284 p = strchr(ent->s, ':'); 285 p = strchr(ent->s, ':');
285 if ((p && strfilter__compare(filter, p + 1)) || 286 if ((p && strfilter__compare(filter, p + 1)) ||
286 strfilter__compare(filter, ent->s)) { 287 strfilter__compare(filter, ent->s)) {
@@ -298,7 +299,7 @@ int probe_file__del_strlist(int fd, struct strlist *namelist)
298 int ret = 0; 299 int ret = 0;
299 struct str_node *ent; 300 struct str_node *ent;
300 301
301 strlist__for_each(ent, namelist) { 302 strlist__for_each_entry(ent, namelist) {
302 ret = __del_trace_probe_event(fd, ent); 303 ret = __del_trace_probe_event(fd, ent);
303 if (ret < 0) 304 if (ret < 0)
304 break; 305 break;
@@ -324,3 +325,533 @@ int probe_file__del_events(int fd, struct strfilter *filter)
324 325
325 return ret; 326 return ret;
326} 327}
328
329/* Caller must ensure to remove this entry from list */
330static void probe_cache_entry__delete(struct probe_cache_entry *entry)
331{
332 if (entry) {
333 BUG_ON(!list_empty(&entry->node));
334
335 strlist__delete(entry->tevlist);
336 clear_perf_probe_event(&entry->pev);
337 zfree(&entry->spev);
338 free(entry);
339 }
340}
341
342static struct probe_cache_entry *
343probe_cache_entry__new(struct perf_probe_event *pev)
344{
345 struct probe_cache_entry *entry = zalloc(sizeof(*entry));
346
347 if (entry) {
348 INIT_LIST_HEAD(&entry->node);
349 entry->tevlist = strlist__new(NULL, NULL);
350 if (!entry->tevlist)
351 zfree(&entry);
352 else if (pev) {
353 entry->spev = synthesize_perf_probe_command(pev);
354 if (!entry->spev ||
355 perf_probe_event__copy(&entry->pev, pev) < 0) {
356 probe_cache_entry__delete(entry);
357 return NULL;
358 }
359 }
360 }
361
362 return entry;
363}
364
365int probe_cache_entry__get_event(struct probe_cache_entry *entry,
366 struct probe_trace_event **tevs)
367{
368 struct probe_trace_event *tev;
369 struct str_node *node;
370 int ret, i;
371
372 ret = strlist__nr_entries(entry->tevlist);
373 if (ret > probe_conf.max_probes)
374 return -E2BIG;
375
376 *tevs = zalloc(ret * sizeof(*tev));
377 if (!*tevs)
378 return -ENOMEM;
379
380 i = 0;
381 strlist__for_each_entry(node, entry->tevlist) {
382 tev = &(*tevs)[i++];
383 ret = parse_probe_trace_command(node->s, tev);
384 if (ret < 0)
385 break;
386 }
387 return i;
388}
389
390/* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */
391static int probe_cache__open(struct probe_cache *pcache, const char *target)
392{
393 char cpath[PATH_MAX];
394 char sbuildid[SBUILD_ID_SIZE];
395 char *dir_name = NULL;
396 bool is_kallsyms = false;
397 int ret, fd;
398
399 if (target && build_id_cache__cached(target)) {
400 /* This is a cached buildid */
401 strncpy(sbuildid, target, SBUILD_ID_SIZE);
402 dir_name = build_id_cache__linkname(sbuildid, NULL, 0);
403 goto found;
404 }
405
406 if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) {
407 target = DSO__NAME_KALLSYMS;
408 is_kallsyms = true;
409 ret = sysfs__sprintf_build_id("/", sbuildid);
410 } else
411 ret = filename__sprintf_build_id(target, sbuildid);
412
413 if (ret < 0) {
414 pr_debug("Failed to get build-id from %s.\n", target);
415 return ret;
416 }
417
418 /* If we have no buildid cache, make it */
419 if (!build_id_cache__cached(sbuildid)) {
420 ret = build_id_cache__add_s(sbuildid, target,
421 is_kallsyms, NULL);
422 if (ret < 0) {
423 pr_debug("Failed to add build-id cache: %s\n", target);
424 return ret;
425 }
426 }
427
428 dir_name = build_id_cache__cachedir(sbuildid, target, is_kallsyms,
429 false);
430found:
431 if (!dir_name) {
432 pr_debug("Failed to get cache from %s\n", target);
433 return -ENOMEM;
434 }
435
436 snprintf(cpath, PATH_MAX, "%s/probes", dir_name);
437 fd = open(cpath, O_CREAT | O_RDWR, 0644);
438 if (fd < 0)
439 pr_debug("Failed to open cache(%d): %s\n", fd, cpath);
440 free(dir_name);
441 pcache->fd = fd;
442
443 return fd;
444}
445
446static int probe_cache__load(struct probe_cache *pcache)
447{
448 struct probe_cache_entry *entry = NULL;
449 char buf[MAX_CMDLEN], *p;
450 int ret = 0;
451 FILE *fp;
452
453 fp = fdopen(dup(pcache->fd), "r");
454 if (!fp)
455 return -EINVAL;
456
457 while (!feof(fp)) {
458 if (!fgets(buf, MAX_CMDLEN, fp))
459 break;
460 p = strchr(buf, '\n');
461 if (p)
462 *p = '\0';
463 /* #perf_probe_event or %sdt_event */
464 if (buf[0] == '#' || buf[0] == '%') {
465 entry = probe_cache_entry__new(NULL);
466 if (!entry) {
467 ret = -ENOMEM;
468 goto out;
469 }
470 if (buf[0] == '%')
471 entry->sdt = true;
472 entry->spev = strdup(buf + 1);
473 if (entry->spev)
474 ret = parse_perf_probe_command(buf + 1,
475 &entry->pev);
476 else
477 ret = -ENOMEM;
478 if (ret < 0) {
479 probe_cache_entry__delete(entry);
480 goto out;
481 }
482 list_add_tail(&entry->node, &pcache->entries);
483 } else { /* trace_probe_event */
484 if (!entry) {
485 ret = -EINVAL;
486 goto out;
487 }
488 strlist__add(entry->tevlist, buf);
489 }
490 }
491out:
492 fclose(fp);
493 return ret;
494}
495
496static struct probe_cache *probe_cache__alloc(void)
497{
498 struct probe_cache *pcache = zalloc(sizeof(*pcache));
499
500 if (pcache) {
501 INIT_LIST_HEAD(&pcache->entries);
502 pcache->fd = -EINVAL;
503 }
504 return pcache;
505}
506
507void probe_cache__purge(struct probe_cache *pcache)
508{
509 struct probe_cache_entry *entry, *n;
510
511 list_for_each_entry_safe(entry, n, &pcache->entries, node) {
512 list_del_init(&entry->node);
513 probe_cache_entry__delete(entry);
514 }
515}
516
517void probe_cache__delete(struct probe_cache *pcache)
518{
519 if (!pcache)
520 return;
521
522 probe_cache__purge(pcache);
523 if (pcache->fd > 0)
524 close(pcache->fd);
525 free(pcache);
526}
527
528struct probe_cache *probe_cache__new(const char *target)
529{
530 struct probe_cache *pcache = probe_cache__alloc();
531 int ret;
532
533 if (!pcache)
534 return NULL;
535
536 ret = probe_cache__open(pcache, target);
537 if (ret < 0) {
538 pr_debug("Cache open error: %d\n", ret);
539 goto out_err;
540 }
541
542 ret = probe_cache__load(pcache);
543 if (ret < 0) {
544 pr_debug("Cache read error: %d\n", ret);
545 goto out_err;
546 }
547
548 return pcache;
549
550out_err:
551 probe_cache__delete(pcache);
552 return NULL;
553}
554
555static bool streql(const char *a, const char *b)
556{
557 if (a == b)
558 return true;
559
560 if (!a || !b)
561 return false;
562
563 return !strcmp(a, b);
564}
565
566struct probe_cache_entry *
567probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
568{
569 struct probe_cache_entry *entry = NULL;
570 char *cmd = synthesize_perf_probe_command(pev);
571
572 if (!cmd)
573 return NULL;
574
575 for_each_probe_cache_entry(entry, pcache) {
576 if (pev->sdt) {
577 if (entry->pev.event &&
578 streql(entry->pev.event, pev->event) &&
579 (!pev->group ||
580 streql(entry->pev.group, pev->group)))
581 goto found;
582
583 continue;
584 }
585 /* Hit if same event name or same command-string */
586 if ((pev->event &&
587 (streql(entry->pev.group, pev->group) &&
588 streql(entry->pev.event, pev->event))) ||
589 (!strcmp(entry->spev, cmd)))
590 goto found;
591 }
592 entry = NULL;
593
594found:
595 free(cmd);
596 return entry;
597}
598
599struct probe_cache_entry *
600probe_cache__find_by_name(struct probe_cache *pcache,
601 const char *group, const char *event)
602{
603 struct probe_cache_entry *entry = NULL;
604
605 for_each_probe_cache_entry(entry, pcache) {
606 /* Hit if same event name or same command-string */
607 if (streql(entry->pev.group, group) &&
608 streql(entry->pev.event, event))
609 goto found;
610 }
611 entry = NULL;
612
613found:
614 return entry;
615}
616
617int probe_cache__add_entry(struct probe_cache *pcache,
618 struct perf_probe_event *pev,
619 struct probe_trace_event *tevs, int ntevs)
620{
621 struct probe_cache_entry *entry = NULL;
622 char *command;
623 int i, ret = 0;
624
625 if (!pcache || !pev || !tevs || ntevs <= 0) {
626 ret = -EINVAL;
627 goto out_err;
628 }
629
630 /* Remove old cache entry */
631 entry = probe_cache__find(pcache, pev);
632 if (entry) {
633 list_del_init(&entry->node);
634 probe_cache_entry__delete(entry);
635 }
636
637 ret = -ENOMEM;
638 entry = probe_cache_entry__new(pev);
639 if (!entry)
640 goto out_err;
641
642 for (i = 0; i < ntevs; i++) {
643 if (!tevs[i].point.symbol)
644 continue;
645
646 command = synthesize_probe_trace_command(&tevs[i]);
647 if (!command)
648 goto out_err;
649 strlist__add(entry->tevlist, command);
650 free(command);
651 }
652 list_add_tail(&entry->node, &pcache->entries);
653 pr_debug("Added probe cache: %d\n", ntevs);
654 return 0;
655
656out_err:
657 pr_debug("Failed to add probe caches\n");
658 probe_cache_entry__delete(entry);
659 return ret;
660}
661
662#ifdef HAVE_GELF_GETNOTE_SUPPORT
663static unsigned long long sdt_note__get_addr(struct sdt_note *note)
664{
665 return note->bit32 ? (unsigned long long)note->addr.a32[0]
666 : (unsigned long long)note->addr.a64[0];
667}
668
669int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
670{
671 struct probe_cache_entry *entry = NULL;
672 struct list_head sdtlist;
673 struct sdt_note *note;
674 char *buf;
675 char sdtgrp[64];
676 int ret;
677
678 INIT_LIST_HEAD(&sdtlist);
679 ret = get_sdt_note_list(&sdtlist, pathname);
680 if (ret < 0) {
681 pr_debug("Failed to get sdt note: %d\n", ret);
682 return ret;
683 }
684 list_for_each_entry(note, &sdtlist, note_list) {
685 ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider);
686 if (ret < 0)
687 break;
688 /* Try to find same-name entry */
689 entry = probe_cache__find_by_name(pcache, sdtgrp, note->name);
690 if (!entry) {
691 entry = probe_cache_entry__new(NULL);
692 if (!entry) {
693 ret = -ENOMEM;
694 break;
695 }
696 entry->sdt = true;
697 ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp,
698 note->name, note->name);
699 if (ret < 0)
700 break;
701 entry->pev.event = strdup(note->name);
702 entry->pev.group = strdup(sdtgrp);
703 list_add_tail(&entry->node, &pcache->entries);
704 }
705 ret = asprintf(&buf, "p:%s/%s %s:0x%llx",
706 sdtgrp, note->name, pathname,
707 sdt_note__get_addr(note));
708 if (ret < 0)
709 break;
710 strlist__add(entry->tevlist, buf);
711 free(buf);
712 entry = NULL;
713 }
714 if (entry) {
715 list_del_init(&entry->node);
716 probe_cache_entry__delete(entry);
717 }
718 cleanup_sdt_note_list(&sdtlist);
719 return ret;
720}
721#endif
722
723static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd)
724{
725 struct str_node *snode;
726 struct stat st;
727 struct iovec iov[3];
728 const char *prefix = entry->sdt ? "%" : "#";
729 int ret;
730 /* Save stat for rollback */
731 ret = fstat(fd, &st);
732 if (ret < 0)
733 return ret;
734
735 pr_debug("Writing cache: %s%s\n", prefix, entry->spev);
736 iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1;
737 iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev);
738 iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1;
739 ret = writev(fd, iov, 3);
740 if (ret < (int)iov[1].iov_len + 2)
741 goto rollback;
742
743 strlist__for_each_entry(snode, entry->tevlist) {
744 iov[0].iov_base = (void *)snode->s;
745 iov[0].iov_len = strlen(snode->s);
746 iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1;
747 ret = writev(fd, iov, 2);
748 if (ret < (int)iov[0].iov_len + 1)
749 goto rollback;
750 }
751 return 0;
752
753rollback:
754 /* Rollback to avoid cache file corruption */
755 if (ret > 0)
756 ret = -1;
757 if (ftruncate(fd, st.st_size) < 0)
758 ret = -2;
759
760 return ret;
761}
762
763int probe_cache__commit(struct probe_cache *pcache)
764{
765 struct probe_cache_entry *entry;
766 int ret = 0;
767
768 /* TBD: if we do not update existing entries, skip it */
769 ret = lseek(pcache->fd, 0, SEEK_SET);
770 if (ret < 0)
771 goto out;
772
773 ret = ftruncate(pcache->fd, 0);
774 if (ret < 0)
775 goto out;
776
777 for_each_probe_cache_entry(entry, pcache) {
778 ret = probe_cache_entry__write(entry, pcache->fd);
779 pr_debug("Cache committed: %d\n", ret);
780 if (ret < 0)
781 break;
782 }
783out:
784 return ret;
785}
786
787static bool probe_cache_entry__compare(struct probe_cache_entry *entry,
788 struct strfilter *filter)
789{
790 char buf[128], *ptr = entry->spev;
791
792 if (entry->pev.event) {
793 snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event);
794 ptr = buf;
795 }
796 return strfilter__compare(filter, ptr);
797}
798
799int probe_cache__filter_purge(struct probe_cache *pcache,
800 struct strfilter *filter)
801{
802 struct probe_cache_entry *entry, *tmp;
803
804 list_for_each_entry_safe(entry, tmp, &pcache->entries, node) {
805 if (probe_cache_entry__compare(entry, filter)) {
806 pr_info("Removed cached event: %s\n", entry->spev);
807 list_del_init(&entry->node);
808 probe_cache_entry__delete(entry);
809 }
810 }
811 return 0;
812}
813
814static int probe_cache__show_entries(struct probe_cache *pcache,
815 struct strfilter *filter)
816{
817 struct probe_cache_entry *entry;
818
819 for_each_probe_cache_entry(entry, pcache) {
820 if (probe_cache_entry__compare(entry, filter))
821 printf("%s\n", entry->spev);
822 }
823 return 0;
824}
825
826/* Show all cached probes */
827int probe_cache__show_all_caches(struct strfilter *filter)
828{
829 struct probe_cache *pcache;
830 struct strlist *bidlist;
831 struct str_node *nd;
832 char *buf = strfilter__string(filter);
833
834 pr_debug("list cache with filter: %s\n", buf);
835 free(buf);
836
837 bidlist = build_id_cache__list_all(true);
838 if (!bidlist) {
839 pr_debug("Failed to get buildids: %d\n", errno);
840 return -EINVAL;
841 }
842 strlist__for_each_entry(nd, bidlist) {
843 pcache = probe_cache__new(nd->s);
844 if (!pcache)
845 continue;
846 if (!list_empty(&pcache->entries)) {
847 buf = build_id_cache__origname(nd->s);
848 printf("%s (%s):\n", buf, nd->s);
849 free(buf);
850 probe_cache__show_entries(pcache, filter);
851 }
852 probe_cache__delete(pcache);
853 }
854 strlist__delete(bidlist);
855
856 return 0;
857}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index 18ac9cf51c34..9577b5c0b487 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -5,9 +5,27 @@
5#include "strfilter.h" 5#include "strfilter.h"
6#include "probe-event.h" 6#include "probe-event.h"
7 7
8/* Cache of probe definitions */
9struct probe_cache_entry {
10 struct list_head node;
11 bool sdt;
12 struct perf_probe_event pev;
13 char *spev;
14 struct strlist *tevlist;
15};
16
17struct probe_cache {
18 int fd;
19 struct list_head entries;
20};
21
8#define PF_FL_UPROBE 1 22#define PF_FL_UPROBE 1
9#define PF_FL_RW 2 23#define PF_FL_RW 2
24#define for_each_probe_cache_entry(entry, pcache) \
25 list_for_each_entry(entry, &pcache->entries, node)
10 26
27/* probe-file.c depends on libelf */
28#ifdef HAVE_LIBELF_SUPPORT
11int probe_file__open(int flag); 29int probe_file__open(int flag);
12int probe_file__open_both(int *kfd, int *ufd, int flag); 30int probe_file__open_both(int *kfd, int *ufd, int flag);
13struct strlist *probe_file__get_namelist(int fd); 31struct strlist *probe_file__get_namelist(int fd);
@@ -18,5 +36,29 @@ int probe_file__get_events(int fd, struct strfilter *filter,
18 struct strlist *plist); 36 struct strlist *plist);
19int probe_file__del_strlist(int fd, struct strlist *namelist); 37int probe_file__del_strlist(int fd, struct strlist *namelist);
20 38
39int probe_cache_entry__get_event(struct probe_cache_entry *entry,
40 struct probe_trace_event **tevs);
21 41
42struct probe_cache *probe_cache__new(const char *target);
43int probe_cache__add_entry(struct probe_cache *pcache,
44 struct perf_probe_event *pev,
45 struct probe_trace_event *tevs, int ntevs);
46int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname);
47int probe_cache__commit(struct probe_cache *pcache);
48void probe_cache__purge(struct probe_cache *pcache);
49void probe_cache__delete(struct probe_cache *pcache);
50int probe_cache__filter_purge(struct probe_cache *pcache,
51 struct strfilter *filter);
52struct probe_cache_entry *probe_cache__find(struct probe_cache *pcache,
53 struct perf_probe_event *pev);
54struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache,
55 const char *group, const char *event);
56int probe_cache__show_all_caches(struct strfilter *filter);
57#else /* ! HAVE_LIBELF_SUPPORT */
58static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused)
59{
60 return NULL;
61}
62#define probe_cache__delete(pcache) do {} while (0)
63#endif
22#endif 64#endif
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 1259839dbf6d..f2d9ff064e2d 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -381,7 +381,7 @@ formatted:
381 if (ret >= 16) 381 if (ret >= 16)
382 ret = -E2BIG; 382 ret = -E2BIG;
383 pr_warning("Failed to convert variable type: %s\n", 383 pr_warning("Failed to convert variable type: %s\n",
384 strerror_r(-ret, sbuf, sizeof(sbuf))); 384 str_error_r(-ret, sbuf, sizeof(sbuf)));
385 return ret; 385 return ret;
386 } 386 }
387 tvar->type = strdup(buf); 387 tvar->type = strdup(buf);
@@ -809,7 +809,7 @@ static int find_lazy_match_lines(struct intlist *list,
809 fp = fopen(fname, "r"); 809 fp = fopen(fname, "r");
810 if (!fp) { 810 if (!fp) {
811 pr_warning("Failed to open %s: %s\n", fname, 811 pr_warning("Failed to open %s: %s\n", fname,
812 strerror_r(errno, sbuf, sizeof(sbuf))); 812 str_error_r(errno, sbuf, sizeof(sbuf)));
813 return -errno; 813 return -errno;
814 } 814 }
815 815
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 36c6862119e3..b7d4f4aeee61 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -13,6 +13,7 @@ util/cpumap.c
13../lib/bitmap.c 13../lib/bitmap.c
14../lib/find_bit.c 14../lib/find_bit.c
15../lib/hweight.c 15../lib/hweight.c
16../lib/vsprintf.c
16util/thread_map.c 17util/thread_map.c
17util/util.c 18util/util.c
18util/xyarray.c 19util/xyarray.c
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 98f127abfa42..a5fbc012e3df 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -2,6 +2,7 @@
2#include <structmember.h> 2#include <structmember.h>
3#include <inttypes.h> 3#include <inttypes.h>
4#include <poll.h> 4#include <poll.h>
5#include <linux/err.h>
5#include "evlist.h" 6#include "evlist.h"
6#include "evsel.h" 7#include "evsel.h"
7#include "event.h" 8#include "event.h"
@@ -47,6 +48,7 @@ PyMODINIT_FUNC initperf(void);
47 48
48struct pyrf_event { 49struct pyrf_event {
49 PyObject_HEAD 50 PyObject_HEAD
51 struct perf_evsel *evsel;
50 struct perf_sample sample; 52 struct perf_sample sample;
51 union perf_event event; 53 union perf_event event;
52}; 54};
@@ -288,6 +290,85 @@ static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
288 return ret; 290 return ret;
289} 291}
290 292
293static bool is_tracepoint(struct pyrf_event *pevent)
294{
295 return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT;
296}
297
298static PyObject*
299tracepoint_field(struct pyrf_event *pe, struct format_field *field)
300{
301 struct pevent *pevent = field->event->pevent;
302 void *data = pe->sample.raw_data;
303 PyObject *ret = NULL;
304 unsigned long long val;
305 unsigned int offset, len;
306
307 if (field->flags & FIELD_IS_ARRAY) {
308 offset = field->offset;
309 len = field->size;
310 if (field->flags & FIELD_IS_DYNAMIC) {
311 val = pevent_read_number(pevent, data + offset, len);
312 offset = val;
313 len = offset >> 16;
314 offset &= 0xffff;
315 }
316 if (field->flags & FIELD_IS_STRING &&
317 is_printable_array(data + offset, len)) {
318 ret = PyString_FromString((char *)data + offset);
319 } else {
320 ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
321 field->flags &= ~FIELD_IS_STRING;
322 }
323 } else {
324 val = pevent_read_number(pevent, data + field->offset,
325 field->size);
326 if (field->flags & FIELD_IS_POINTER)
327 ret = PyLong_FromUnsignedLong((unsigned long) val);
328 else if (field->flags & FIELD_IS_SIGNED)
329 ret = PyLong_FromLong((long) val);
330 else
331 ret = PyLong_FromUnsignedLong((unsigned long) val);
332 }
333
334 return ret;
335}
336
337static PyObject*
338get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
339{
340 const char *str = PyString_AsString(PyObject_Str(attr_name));
341 struct perf_evsel *evsel = pevent->evsel;
342 struct format_field *field;
343
344 if (!evsel->tp_format) {
345 struct event_format *tp_format;
346
347 tp_format = trace_event__tp_format_id(evsel->attr.config);
348 if (!tp_format)
349 return NULL;
350
351 evsel->tp_format = tp_format;
352 }
353
354 field = pevent_find_any_field(evsel->tp_format, str);
355 if (!field)
356 return NULL;
357
358 return tracepoint_field(pevent, field);
359}
360
361static PyObject*
362pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
363{
364 PyObject *obj = NULL;
365
366 if (is_tracepoint(pevent))
367 obj = get_tracepoint_field(pevent, attr_name);
368
369 return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
370}
371
291static PyTypeObject pyrf_sample_event__type = { 372static PyTypeObject pyrf_sample_event__type = {
292 PyVarObject_HEAD_INIT(NULL, 0) 373 PyVarObject_HEAD_INIT(NULL, 0)
293 .tp_name = "perf.sample_event", 374 .tp_name = "perf.sample_event",
@@ -296,6 +377,7 @@ static PyTypeObject pyrf_sample_event__type = {
296 .tp_doc = pyrf_sample_event__doc, 377 .tp_doc = pyrf_sample_event__doc,
297 .tp_members = pyrf_sample_event__members, 378 .tp_members = pyrf_sample_event__members,
298 .tp_repr = (reprfunc)pyrf_sample_event__repr, 379 .tp_repr = (reprfunc)pyrf_sample_event__repr,
380 .tp_getattro = (getattrofunc) pyrf_sample_event__getattro,
299}; 381};
300 382
301static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object."); 383static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
@@ -653,6 +735,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
653 attr.precise_ip = precise_ip; 735 attr.precise_ip = precise_ip;
654 attr.mmap_data = mmap_data; 736 attr.mmap_data = mmap_data;
655 attr.sample_id_all = sample_id_all; 737 attr.sample_id_all = sample_id_all;
738 attr.size = sizeof(attr);
656 739
657 perf_evsel__init(&pevsel->evsel, &attr, idx); 740 perf_evsel__init(&pevsel->evsel, &attr, idx);
658 return 0; 741 return 0;
@@ -863,13 +946,22 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
863 if (event != NULL) { 946 if (event != NULL) {
864 PyObject *pyevent = pyrf_event__new(event); 947 PyObject *pyevent = pyrf_event__new(event);
865 struct pyrf_event *pevent = (struct pyrf_event *)pyevent; 948 struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
866 949 struct perf_evsel *evsel;
867 perf_evlist__mmap_consume(evlist, cpu);
868 950
869 if (pyevent == NULL) 951 if (pyevent == NULL)
870 return PyErr_NoMemory(); 952 return PyErr_NoMemory();
871 953
872 err = perf_evlist__parse_sample(evlist, event, &pevent->sample); 954 evsel = perf_evlist__event2evsel(evlist, event);
955 if (!evsel)
956 return Py_None;
957
958 pevent->evsel = evsel;
959
960 err = perf_evsel__parse_sample(evsel, event, &pevent->sample);
961
962 /* Consume the even only after we parsed it out. */
963 perf_evlist__mmap_consume(evlist, cpu);
964
873 if (err) 965 if (err)
874 return PyErr_Format(PyExc_OSError, 966 return PyErr_Format(PyExc_OSError,
875 "perf: can't parse sample, err=%d", err); 967 "perf: can't parse sample, err=%d", err);
@@ -957,7 +1049,7 @@ static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
957 if (i >= pevlist->evlist.nr_entries) 1049 if (i >= pevlist->evlist.nr_entries)
958 return NULL; 1050 return NULL;
959 1051
960 evlist__for_each(&pevlist->evlist, pos) { 1052 evlist__for_each_entry(&pevlist->evlist, pos) {
961 if (i-- == 0) 1053 if (i-- == 0)
962 break; 1054 break;
963 } 1055 }
@@ -1073,7 +1165,32 @@ static struct {
1073 { .name = NULL, }, 1165 { .name = NULL, },
1074}; 1166};
1075 1167
1168static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
1169 PyObject *args, PyObject *kwargs)
1170{
1171 struct event_format *tp_format;
1172 static char *kwlist[] = { "sys", "name", NULL };
1173 char *sys = NULL;
1174 char *name = NULL;
1175
1176 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist,
1177 &sys, &name))
1178 return NULL;
1179
1180 tp_format = trace_event__tp_format(sys, name);
1181 if (IS_ERR(tp_format))
1182 return PyInt_FromLong(-1);
1183
1184 return PyInt_FromLong(tp_format->id);
1185}
1186
1076static PyMethodDef perf__methods[] = { 1187static PyMethodDef perf__methods[] = {
1188 {
1189 .ml_name = "tracepoint",
1190 .ml_meth = (PyCFunction) pyrf__tracepoint,
1191 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1192 .ml_doc = PyDoc_STR("Get tracepoint config.")
1193 },
1077 { .ml_name = NULL, } 1194 { .ml_name = NULL, }
1078}; 1195};
1079 1196
@@ -1100,6 +1217,33 @@ PyMODINIT_FUNC initperf(void)
1100 Py_INCREF(&pyrf_evsel__type); 1217 Py_INCREF(&pyrf_evsel__type);
1101 PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type); 1218 PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
1102 1219
1220 Py_INCREF(&pyrf_mmap_event__type);
1221 PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type);
1222
1223 Py_INCREF(&pyrf_lost_event__type);
1224 PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type);
1225
1226 Py_INCREF(&pyrf_comm_event__type);
1227 PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type);
1228
1229 Py_INCREF(&pyrf_task_event__type);
1230 PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
1231
1232 Py_INCREF(&pyrf_throttle_event__type);
1233 PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type);
1234
1235 Py_INCREF(&pyrf_task_event__type);
1236 PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
1237
1238 Py_INCREF(&pyrf_read_event__type);
1239 PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type);
1240
1241 Py_INCREF(&pyrf_sample_event__type);
1242 PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type);
1243
1244 Py_INCREF(&pyrf_context_switch_event__type);
1245 PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type);
1246
1103 Py_INCREF(&pyrf_thread_map__type); 1247 Py_INCREF(&pyrf_thread_map__type);
1104 PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type); 1248 PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
1105 1249
diff --git a/tools/perf/util/quote.c b/tools/perf/util/quote.c
index c6d4ee2de752..639d1da2f978 100644
--- a/tools/perf/util/quote.c
+++ b/tools/perf/util/quote.c
@@ -1,5 +1,7 @@
1#include "cache.h" 1#include <stdlib.h>
2#include "strbuf.h"
2#include "quote.h" 3#include "quote.h"
4#include "util.h"
3 5
4/* Help to copy the thing properly quoted for the shell safety. 6/* Help to copy the thing properly quoted for the shell safety.
5 * any single quote is replaced with '\'', any exclamation point 7 * any single quote is replaced with '\'', any exclamation point
diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h
index e1ec19146fb0..055ca45bed99 100644
--- a/tools/perf/util/quote.h
+++ b/tools/perf/util/quote.h
@@ -2,7 +2,6 @@
2#define __PERF_QUOTE_H 2#define __PERF_QUOTE_H
3 3
4#include <stddef.h> 4#include <stddef.h>
5#include <stdio.h>
6 5
7/* Help to copy the thing properly quoted for the shell safety. 6/* Help to copy the thing properly quoted for the shell safety.
8 * any single quote is replaced with '\'', any exclamation point 7 * any single quote is replaced with '\'', any exclamation point
@@ -24,6 +23,8 @@
24 * sq_quote() in a real application. 23 * sq_quote() in a real application.
25 */ 24 */
26 25
26struct strbuf;
27
27int sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); 28int sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
28 29
29#endif /* __PERF_QUOTE_H */ 30#endif /* __PERF_QUOTE_H */
diff --git a/tools/perf/util/rb_resort.h b/tools/perf/util/rb_resort.h
index abc76e3d3098..808cc45611fe 100644
--- a/tools/perf/util/rb_resort.h
+++ b/tools/perf/util/rb_resort.h
@@ -35,7 +35,7 @@ DEFINE_RB_RESORT_RB(threads, strcmp(a->thread->shortname,
35 35
36 struct rb_node *nd; 36 struct rb_node *nd;
37 37
38 resort_rb__for_each(nd, threads) { 38 resort_rb__for_each_entry(nd, threads) {
39 struct thread *t = threads_entry; 39 struct thread *t = threads_entry;
40 printf("%s: %d\n", t->shortname, t->tid); 40 printf("%s: %d\n", t->shortname, t->tid);
41 } 41 }
@@ -123,7 +123,7 @@ static void __name##_sorted__init_entry(struct rb_node *nd, \
123struct __name##_sorted_entry *__name##_entry; \ 123struct __name##_sorted_entry *__name##_entry; \
124struct __name##_sorted *__name = __name##_sorted__new 124struct __name##_sorted *__name = __name##_sorted__new
125 125
126#define resort_rb__for_each(__nd, __name) \ 126#define resort_rb__for_each_entry(__nd, __name) \
127 for (__nd = rb_first(&__name->entries); \ 127 for (__nd = rb_first(&__name->entries); \
128 __name##_entry = rb_entry(__nd, struct __name##_sorted_entry, \ 128 __name##_entry = rb_entry(__nd, struct __name##_sorted_entry, \
129 rb_node), __nd; \ 129 rb_node), __nd; \
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 481792c7484b..98bf584853ea 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -148,7 +148,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
148 148
149 use_comm_exec = perf_can_comm_exec(); 149 use_comm_exec = perf_can_comm_exec();
150 150
151 evlist__for_each(evlist, evsel) { 151 evlist__for_each_entry(evlist, evsel) {
152 perf_evsel__config(evsel, opts, callchain); 152 perf_evsel__config(evsel, opts, callchain);
153 if (evsel->tracking && use_comm_exec) 153 if (evsel->tracking && use_comm_exec)
154 evsel->attr.comm_exec = 1; 154 evsel->attr.comm_exec = 1;
@@ -161,18 +161,18 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
161 * match the id. 161 * match the id.
162 */ 162 */
163 use_sample_identifier = perf_can_sample_identifier(); 163 use_sample_identifier = perf_can_sample_identifier();
164 evlist__for_each(evlist, evsel) 164 evlist__for_each_entry(evlist, evsel)
165 perf_evsel__set_sample_id(evsel, use_sample_identifier); 165 perf_evsel__set_sample_id(evsel, use_sample_identifier);
166 } else if (evlist->nr_entries > 1) { 166 } else if (evlist->nr_entries > 1) {
167 struct perf_evsel *first = perf_evlist__first(evlist); 167 struct perf_evsel *first = perf_evlist__first(evlist);
168 168
169 evlist__for_each(evlist, evsel) { 169 evlist__for_each_entry(evlist, evsel) {
170 if (evsel->attr.sample_type == first->attr.sample_type) 170 if (evsel->attr.sample_type == first->attr.sample_type)
171 continue; 171 continue;
172 use_sample_identifier = perf_can_sample_identifier(); 172 use_sample_identifier = perf_can_sample_identifier();
173 break; 173 break;
174 } 174 }
175 evlist__for_each(evlist, evsel) 175 evlist__for_each_entry(evlist, evsel)
176 perf_evsel__set_sample_id(evsel, use_sample_identifier); 176 perf_evsel__set_sample_id(evsel, use_sample_identifier);
177 } 177 }
178 178
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index ff134700bf30..e0203b979474 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -273,7 +273,7 @@ static PyObject *get_field_numeric_entry(struct event_format *event,
273 struct format_field *field, void *data) 273 struct format_field *field, void *data)
274{ 274{
275 bool is_array = field->flags & FIELD_IS_ARRAY; 275 bool is_array = field->flags & FIELD_IS_ARRAY;
276 PyObject *obj, *list = NULL; 276 PyObject *obj = NULL, *list = NULL;
277 unsigned long long val; 277 unsigned long long val;
278 unsigned int item_size, n_items, i; 278 unsigned int item_size, n_items, i;
279 279
@@ -386,13 +386,12 @@ exit:
386 return pylist; 386 return pylist;
387} 387}
388 388
389
390static void python_process_tracepoint(struct perf_sample *sample, 389static void python_process_tracepoint(struct perf_sample *sample,
391 struct perf_evsel *evsel, 390 struct perf_evsel *evsel,
392 struct addr_location *al) 391 struct addr_location *al)
393{ 392{
394 struct event_format *event = evsel->tp_format; 393 struct event_format *event = evsel->tp_format;
395 PyObject *handler, *context, *t, *obj, *callchain; 394 PyObject *handler, *context, *t, *obj = NULL, *callchain;
396 PyObject *dict = NULL; 395 PyObject *dict = NULL;
397 static char handler_name[256]; 396 static char handler_name[256];
398 struct format_field *field; 397 struct format_field *field;
@@ -457,14 +456,26 @@ static void python_process_tracepoint(struct perf_sample *sample,
457 pydict_set_item_string_decref(dict, "common_callchain", callchain); 456 pydict_set_item_string_decref(dict, "common_callchain", callchain);
458 } 457 }
459 for (field = event->format.fields; field; field = field->next) { 458 for (field = event->format.fields; field; field = field->next) {
460 if (field->flags & FIELD_IS_STRING) { 459 unsigned int offset, len;
461 int offset; 460 unsigned long long val;
461
462 if (field->flags & FIELD_IS_ARRAY) {
463 offset = field->offset;
464 len = field->size;
462 if (field->flags & FIELD_IS_DYNAMIC) { 465 if (field->flags & FIELD_IS_DYNAMIC) {
463 offset = *(int *)(data + field->offset); 466 val = pevent_read_number(scripting_context->pevent,
467 data + offset, len);
468 offset = val;
469 len = offset >> 16;
464 offset &= 0xffff; 470 offset &= 0xffff;
465 } else 471 }
466 offset = field->offset; 472 if (field->flags & FIELD_IS_STRING &&
467 obj = PyString_FromString((char *)data + offset); 473 is_printable_array(data + offset, len)) {
474 obj = PyString_FromString((char *) data + offset);
475 } else {
476 obj = PyByteArray_FromStringAndSize((const char *) data + offset, len);
477 field->flags &= ~FIELD_IS_STRING;
478 }
468 } else { /* FIELD_IS_NUMERIC */ 479 } else { /* FIELD_IS_NUMERIC */
469 obj = get_field_numeric_entry(event, field, data); 480 obj = get_field_numeric_entry(event, field, data);
470 } 481 }
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5214974e841a..5d61242a6e64 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -83,7 +83,7 @@ static bool perf_session__has_comm_exec(struct perf_session *session)
83{ 83{
84 struct perf_evsel *evsel; 84 struct perf_evsel *evsel;
85 85
86 evlist__for_each(session->evlist, evsel) { 86 evlist__for_each_entry(session->evlist, evsel) {
87 if (evsel->attr.comm_exec) 87 if (evsel->attr.comm_exec)
88 return true; 88 return true;
89 } 89 }
@@ -178,6 +178,8 @@ static void perf_session__delete_threads(struct perf_session *session)
178 178
179void perf_session__delete(struct perf_session *session) 179void perf_session__delete(struct perf_session *session)
180{ 180{
181 if (session == NULL)
182 return;
181 auxtrace__free(session); 183 auxtrace__free(session);
182 auxtrace_index__free(&session->auxtrace_index); 184 auxtrace_index__free(&session->auxtrace_index);
183 perf_session__destroy_kernel_maps(session); 185 perf_session__destroy_kernel_maps(session);
@@ -593,6 +595,7 @@ do { \
593 if (bswap_safe(f, 0)) \ 595 if (bswap_safe(f, 0)) \
594 attr->f = bswap_##sz(attr->f); \ 596 attr->f = bswap_##sz(attr->f); \
595} while(0) 597} while(0)
598#define bswap_field_16(f) bswap_field(f, 16)
596#define bswap_field_32(f) bswap_field(f, 32) 599#define bswap_field_32(f) bswap_field(f, 32)
597#define bswap_field_64(f) bswap_field(f, 64) 600#define bswap_field_64(f) bswap_field(f, 64)
598 601
@@ -608,6 +611,7 @@ do { \
608 bswap_field_64(sample_regs_user); 611 bswap_field_64(sample_regs_user);
609 bswap_field_32(sample_stack_user); 612 bswap_field_32(sample_stack_user);
610 bswap_field_32(aux_watermark); 613 bswap_field_32(aux_watermark);
614 bswap_field_16(sample_max_stack);
611 615
612 /* 616 /*
613 * After read_format are bitfields. Check read_format because 617 * After read_format are bitfields. Check read_format because
@@ -1495,10 +1499,27 @@ int perf_session__register_idle_thread(struct perf_session *session)
1495 return err; 1499 return err;
1496} 1500}
1497 1501
1502static void
1503perf_session__warn_order(const struct perf_session *session)
1504{
1505 const struct ordered_events *oe = &session->ordered_events;
1506 struct perf_evsel *evsel;
1507 bool should_warn = true;
1508
1509 evlist__for_each_entry(session->evlist, evsel) {
1510 if (evsel->attr.write_backward)
1511 should_warn = false;
1512 }
1513
1514 if (!should_warn)
1515 return;
1516 if (oe->nr_unordered_events != 0)
1517 ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events);
1518}
1519
1498static void perf_session__warn_about_errors(const struct perf_session *session) 1520static void perf_session__warn_about_errors(const struct perf_session *session)
1499{ 1521{
1500 const struct events_stats *stats = &session->evlist->stats; 1522 const struct events_stats *stats = &session->evlist->stats;
1501 const struct ordered_events *oe = &session->ordered_events;
1502 1523
1503 if (session->tool->lost == perf_event__process_lost && 1524 if (session->tool->lost == perf_event__process_lost &&
1504 stats->nr_events[PERF_RECORD_LOST] != 0) { 1525 stats->nr_events[PERF_RECORD_LOST] != 0) {
@@ -1555,8 +1576,7 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
1555 stats->nr_unprocessable_samples); 1576 stats->nr_unprocessable_samples);
1556 } 1577 }
1557 1578
1558 if (oe->nr_unordered_events != 0) 1579 perf_session__warn_order(session);
1559 ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events);
1560 1580
1561 events_stats__auxtrace_error_warn(stats); 1581 events_stats__auxtrace_error_warn(stats);
1562 1582
@@ -1868,7 +1888,7 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg)
1868{ 1888{
1869 struct perf_evsel *evsel; 1889 struct perf_evsel *evsel;
1870 1890
1871 evlist__for_each(session->evlist, evsel) { 1891 evlist__for_each_entry(session->evlist, evsel) {
1872 if (evsel->attr.type == PERF_TYPE_TRACEPOINT) 1892 if (evsel->attr.type == PERF_TYPE_TRACEPOINT)
1873 return true; 1893 return true;
1874 } 1894 }
@@ -1950,7 +1970,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1950{ 1970{
1951 struct perf_evsel *pos; 1971 struct perf_evsel *pos;
1952 1972
1953 evlist__for_each(session->evlist, pos) { 1973 evlist__for_each_entry(session->evlist, pos) {
1954 if (pos->attr.type == type) 1974 if (pos->attr.type == type)
1955 return pos; 1975 return pos;
1956 } 1976 }
@@ -2105,7 +2125,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool,
2105 max_nr = (UINT16_MAX - sizeof(struct id_index_event)) / 2125 max_nr = (UINT16_MAX - sizeof(struct id_index_event)) /
2106 sizeof(struct id_index_entry); 2126 sizeof(struct id_index_entry);
2107 2127
2108 evlist__for_each(evlist, evsel) 2128 evlist__for_each_entry(evlist, evsel)
2109 nr += evsel->ids; 2129 nr += evsel->ids;
2110 2130
2111 n = nr > max_nr ? max_nr : nr; 2131 n = nr > max_nr ? max_nr : nr;
@@ -2118,7 +2138,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool,
2118 ev->id_index.header.size = sz; 2138 ev->id_index.header.size = sz;
2119 ev->id_index.nr = n; 2139 ev->id_index.nr = n;
2120 2140
2121 evlist__for_each(evlist, evsel) { 2141 evlist__for_each_entry(evlist, evsel) {
2122 u32 j; 2142 u32 j;
2123 2143
2124 for (j = 0; j < evsel->ids; j++) { 2144 for (j = 0; j < evsel->ids; j++) {
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index c4e9bd70723c..947d21f38398 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -79,8 +79,8 @@ static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
79{ 79{
80 const char *comm = thread__comm_str(he->thread); 80 const char *comm = thread__comm_str(he->thread);
81 81
82 width = max(7U, width) - 6; 82 width = max(7U, width) - 8;
83 return repsep_snprintf(bf, size, "%5d:%-*.*s", he->thread->tid, 83 return repsep_snprintf(bf, size, "%7d:%-*.*s", he->thread->tid,
84 width, width, comm ?: ""); 84 width, width, comm ?: "");
85} 85}
86 86
@@ -95,7 +95,7 @@ static int hist_entry__thread_filter(struct hist_entry *he, int type, const void
95} 95}
96 96
97struct sort_entry sort_thread = { 97struct sort_entry sort_thread = {
98 .se_header = " Pid:Command", 98 .se_header = " Pid:Command",
99 .se_cmp = sort__thread_cmp, 99 .se_cmp = sort__thread_cmp,
100 .se_snprintf = hist_entry__thread_snprintf, 100 .se_snprintf = hist_entry__thread_snprintf,
101 .se_filter = hist_entry__thread_filter, 101 .se_filter = hist_entry__thread_filter,
@@ -1218,7 +1218,7 @@ struct sort_entry sort_mem_daddr_dso = {
1218 .se_header = "Data Object", 1218 .se_header = "Data Object",
1219 .se_cmp = sort__dso_daddr_cmp, 1219 .se_cmp = sort__dso_daddr_cmp,
1220 .se_snprintf = hist_entry__dso_daddr_snprintf, 1220 .se_snprintf = hist_entry__dso_daddr_snprintf,
1221 .se_width_idx = HISTC_MEM_DADDR_SYMBOL, 1221 .se_width_idx = HISTC_MEM_DADDR_DSO,
1222}; 1222};
1223 1223
1224struct sort_entry sort_mem_locked = { 1224struct sort_entry sort_mem_locked = {
@@ -1488,7 +1488,7 @@ void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists)
1488} 1488}
1489 1489
1490static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 1490static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1491 struct perf_evsel *evsel) 1491 struct hists *hists)
1492{ 1492{
1493 struct hpp_sort_entry *hse; 1493 struct hpp_sort_entry *hse;
1494 size_t len = fmt->user_len; 1494 size_t len = fmt->user_len;
@@ -1496,14 +1496,14 @@ static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1496 hse = container_of(fmt, struct hpp_sort_entry, hpp); 1496 hse = container_of(fmt, struct hpp_sort_entry, hpp);
1497 1497
1498 if (!len) 1498 if (!len)
1499 len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx); 1499 len = hists__col_len(hists, hse->se->se_width_idx);
1500 1500
1501 return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name); 1501 return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name);
1502} 1502}
1503 1503
1504static int __sort__hpp_width(struct perf_hpp_fmt *fmt, 1504static int __sort__hpp_width(struct perf_hpp_fmt *fmt,
1505 struct perf_hpp *hpp __maybe_unused, 1505 struct perf_hpp *hpp __maybe_unused,
1506 struct perf_evsel *evsel) 1506 struct hists *hists)
1507{ 1507{
1508 struct hpp_sort_entry *hse; 1508 struct hpp_sort_entry *hse;
1509 size_t len = fmt->user_len; 1509 size_t len = fmt->user_len;
@@ -1511,7 +1511,7 @@ static int __sort__hpp_width(struct perf_hpp_fmt *fmt,
1511 hse = container_of(fmt, struct hpp_sort_entry, hpp); 1511 hse = container_of(fmt, struct hpp_sort_entry, hpp);
1512 1512
1513 if (!len) 1513 if (!len)
1514 len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx); 1514 len = hists__col_len(hists, hse->se->se_width_idx);
1515 1515
1516 return len; 1516 return len;
1517} 1517}
@@ -1793,7 +1793,7 @@ static void update_dynamic_len(struct hpp_dynamic_entry *hde,
1793} 1793}
1794 1794
1795static int __sort__hde_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, 1795static int __sort__hde_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1796 struct perf_evsel *evsel __maybe_unused) 1796 struct hists *hists __maybe_unused)
1797{ 1797{
1798 struct hpp_dynamic_entry *hde; 1798 struct hpp_dynamic_entry *hde;
1799 size_t len = fmt->user_len; 1799 size_t len = fmt->user_len;
@@ -1808,7 +1808,7 @@ static int __sort__hde_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1808 1808
1809static int __sort__hde_width(struct perf_hpp_fmt *fmt, 1809static int __sort__hde_width(struct perf_hpp_fmt *fmt,
1810 struct perf_hpp *hpp __maybe_unused, 1810 struct perf_hpp *hpp __maybe_unused,
1811 struct perf_evsel *evsel __maybe_unused) 1811 struct hists *hists __maybe_unused)
1812{ 1812{
1813 struct hpp_dynamic_entry *hde; 1813 struct hpp_dynamic_entry *hde;
1814 size_t len = fmt->user_len; 1814 size_t len = fmt->user_len;
@@ -2069,7 +2069,7 @@ static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_nam
2069 } 2069 }
2070 2070
2071 full_name = !!strchr(event_name, ':'); 2071 full_name = !!strchr(event_name, ':');
2072 evlist__for_each(evlist, pos) { 2072 evlist__for_each_entry(evlist, pos) {
2073 /* case 2 */ 2073 /* case 2 */
2074 if (full_name && !strcmp(pos->name, event_name)) 2074 if (full_name && !strcmp(pos->name, event_name))
2075 return pos; 2075 return pos;
@@ -2125,7 +2125,7 @@ static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace,
2125 int ret; 2125 int ret;
2126 struct perf_evsel *evsel; 2126 struct perf_evsel *evsel;
2127 2127
2128 evlist__for_each(evlist, evsel) { 2128 evlist__for_each_entry(evlist, evsel) {
2129 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) 2129 if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
2130 continue; 2130 continue;
2131 2131
@@ -2143,7 +2143,7 @@ static int add_all_matching_fields(struct perf_evlist *evlist,
2143 struct perf_evsel *evsel; 2143 struct perf_evsel *evsel;
2144 struct format_field *field; 2144 struct format_field *field;
2145 2145
2146 evlist__for_each(evlist, evsel) { 2146 evlist__for_each_entry(evlist, evsel) {
2147 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) 2147 if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
2148 continue; 2148 continue;
2149 2149
@@ -2381,6 +2381,9 @@ static int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
2381 if (sort__mode != SORT_MODE__MEMORY) 2381 if (sort__mode != SORT_MODE__MEMORY)
2382 return -EINVAL; 2382 return -EINVAL;
2383 2383
2384 if (sd->entry == &sort_mem_dcacheline && cacheline_size == 0)
2385 return -EINVAL;
2386
2384 if (sd->entry == &sort_mem_daddr_sym) 2387 if (sd->entry == &sort_mem_daddr_sym)
2385 list->sym = 1; 2388 list->sym = 1;
2386 2389
@@ -2424,7 +2427,10 @@ static int setup_sort_list(struct perf_hpp_list *list, char *str,
2424 if (*tok) { 2427 if (*tok) {
2425 ret = sort_dimension__add(list, tok, evlist, level); 2428 ret = sort_dimension__add(list, tok, evlist, level);
2426 if (ret == -EINVAL) { 2429 if (ret == -EINVAL) {
2427 error("Invalid --sort key: `%s'", tok); 2430 if (!cacheline_size && !strncasecmp(tok, "dcacheline", strlen(tok)))
2431 error("The \"dcacheline\" --sort key needs to know the cacheline size and it couldn't be determined on this system");
2432 else
2433 error("Invalid --sort key: `%s'", tok);
2428 break; 2434 break;
2429 } else if (ret == -ESRCH) { 2435 } else if (ret == -ESRCH) {
2430 error("Unknown --sort key: `%s'", tok); 2436 error("Unknown --sort key: `%s'", tok);
@@ -2456,7 +2462,7 @@ static const char *get_default_sort_order(struct perf_evlist *evlist)
2456 if (evlist == NULL) 2462 if (evlist == NULL)
2457 goto out_no_evlist; 2463 goto out_no_evlist;
2458 2464
2459 evlist__for_each(evlist, evsel) { 2465 evlist__for_each_entry(evlist, evsel) {
2460 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) { 2466 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2461 use_trace = false; 2467 use_trace = false;
2462 break; 2468 break;
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index ebb59cacd092..7ca37ea17395 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -67,6 +67,11 @@ struct hist_entry_diff {
67 }; 67 };
68}; 68};
69 69
70struct hist_entry_ops {
71 void *(*new)(size_t size);
72 void (*free)(void *ptr);
73};
74
70/** 75/**
71 * struct hist_entry - histogram entry 76 * struct hist_entry - histogram entry
72 * 77 *
@@ -125,6 +130,7 @@ struct hist_entry {
125 void *trace_output; 130 void *trace_output;
126 struct perf_hpp_list *hpp_list; 131 struct perf_hpp_list *hpp_list;
127 struct hist_entry *parent_he; 132 struct hist_entry *parent_he;
133 struct hist_entry_ops *ops;
128 union { 134 union {
129 /* this is for hierarchical entry structure */ 135 /* this is for hierarchical entry structure */
130 struct { 136 struct {
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index aa9efe08762b..8a2bbd2a4d82 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -36,6 +36,11 @@ static struct stats runtime_dtlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
36static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS]; 36static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS];
37static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS]; 37static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS];
38static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS]; 38static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS];
39static struct stats runtime_topdown_total_slots[NUM_CTX][MAX_NR_CPUS];
40static struct stats runtime_topdown_slots_issued[NUM_CTX][MAX_NR_CPUS];
41static struct stats runtime_topdown_slots_retired[NUM_CTX][MAX_NR_CPUS];
42static struct stats runtime_topdown_fetch_bubbles[NUM_CTX][MAX_NR_CPUS];
43static struct stats runtime_topdown_recovery_bubbles[NUM_CTX][MAX_NR_CPUS];
39static bool have_frontend_stalled; 44static bool have_frontend_stalled;
40 45
41struct stats walltime_nsecs_stats; 46struct stats walltime_nsecs_stats;
@@ -82,6 +87,11 @@ void perf_stat__reset_shadow_stats(void)
82 sizeof(runtime_transaction_stats)); 87 sizeof(runtime_transaction_stats));
83 memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats)); 88 memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
84 memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats)); 89 memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
90 memset(runtime_topdown_total_slots, 0, sizeof(runtime_topdown_total_slots));
91 memset(runtime_topdown_slots_retired, 0, sizeof(runtime_topdown_slots_retired));
92 memset(runtime_topdown_slots_issued, 0, sizeof(runtime_topdown_slots_issued));
93 memset(runtime_topdown_fetch_bubbles, 0, sizeof(runtime_topdown_fetch_bubbles));
94 memset(runtime_topdown_recovery_bubbles, 0, sizeof(runtime_topdown_recovery_bubbles));
85} 95}
86 96
87/* 97/*
@@ -105,6 +115,16 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
105 update_stats(&runtime_transaction_stats[ctx][cpu], count[0]); 115 update_stats(&runtime_transaction_stats[ctx][cpu], count[0]);
106 else if (perf_stat_evsel__is(counter, ELISION_START)) 116 else if (perf_stat_evsel__is(counter, ELISION_START))
107 update_stats(&runtime_elision_stats[ctx][cpu], count[0]); 117 update_stats(&runtime_elision_stats[ctx][cpu], count[0]);
118 else if (perf_stat_evsel__is(counter, TOPDOWN_TOTAL_SLOTS))
119 update_stats(&runtime_topdown_total_slots[ctx][cpu], count[0]);
120 else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_ISSUED))
121 update_stats(&runtime_topdown_slots_issued[ctx][cpu], count[0]);
122 else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_RETIRED))
123 update_stats(&runtime_topdown_slots_retired[ctx][cpu], count[0]);
124 else if (perf_stat_evsel__is(counter, TOPDOWN_FETCH_BUBBLES))
125 update_stats(&runtime_topdown_fetch_bubbles[ctx][cpu],count[0]);
126 else if (perf_stat_evsel__is(counter, TOPDOWN_RECOVERY_BUBBLES))
127 update_stats(&runtime_topdown_recovery_bubbles[ctx][cpu], count[0]);
108 else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) 128 else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
109 update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]); 129 update_stats(&runtime_stalled_cycles_front_stats[ctx][cpu], count[0]);
110 else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND)) 130 else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
@@ -302,6 +322,107 @@ static void print_ll_cache_misses(int cpu,
302 out->print_metric(out->ctx, color, "%7.2f%%", "of all LL-cache hits", ratio); 322 out->print_metric(out->ctx, color, "%7.2f%%", "of all LL-cache hits", ratio);
303} 323}
304 324
325/*
326 * High level "TopDown" CPU core pipe line bottleneck break down.
327 *
328 * Basic concept following
329 * Yasin, A Top Down Method for Performance analysis and Counter architecture
330 * ISPASS14
331 *
332 * The CPU pipeline is divided into 4 areas that can be bottlenecks:
333 *
334 * Frontend -> Backend -> Retiring
335 * BadSpeculation in addition means out of order execution that is thrown away
336 * (for example branch mispredictions)
337 * Frontend is instruction decoding.
338 * Backend is execution, like computation and accessing data in memory
339 * Retiring is good execution that is not directly bottlenecked
340 *
341 * The formulas are computed in slots.
342 * A slot is an entry in the pipeline each for the pipeline width
343 * (for example a 4-wide pipeline has 4 slots for each cycle)
344 *
345 * Formulas:
346 * BadSpeculation = ((SlotsIssued - SlotsRetired) + RecoveryBubbles) /
347 * TotalSlots
348 * Retiring = SlotsRetired / TotalSlots
349 * FrontendBound = FetchBubbles / TotalSlots
350 * BackendBound = 1.0 - BadSpeculation - Retiring - FrontendBound
351 *
352 * The kernel provides the mapping to the low level CPU events and any scaling
353 * needed for the CPU pipeline width, for example:
354 *
355 * TotalSlots = Cycles * 4
356 *
357 * The scaling factor is communicated in the sysfs unit.
358 *
359 * In some cases the CPU may not be able to measure all the formulas due to
360 * missing events. In this case multiple formulas are combined, as possible.
361 *
362 * Full TopDown supports more levels to sub-divide each area: for example
363 * BackendBound into computing bound and memory bound. For now we only
364 * support Level 1 TopDown.
365 */
366
367static double sanitize_val(double x)
368{
369 if (x < 0 && x >= -0.02)
370 return 0.0;
371 return x;
372}
373
374static double td_total_slots(int ctx, int cpu)
375{
376 return avg_stats(&runtime_topdown_total_slots[ctx][cpu]);
377}
378
379static double td_bad_spec(int ctx, int cpu)
380{
381 double bad_spec = 0;
382 double total_slots;
383 double total;
384
385 total = avg_stats(&runtime_topdown_slots_issued[ctx][cpu]) -
386 avg_stats(&runtime_topdown_slots_retired[ctx][cpu]) +
387 avg_stats(&runtime_topdown_recovery_bubbles[ctx][cpu]);
388 total_slots = td_total_slots(ctx, cpu);
389 if (total_slots)
390 bad_spec = total / total_slots;
391 return sanitize_val(bad_spec);
392}
393
394static double td_retiring(int ctx, int cpu)
395{
396 double retiring = 0;
397 double total_slots = td_total_slots(ctx, cpu);
398 double ret_slots = avg_stats(&runtime_topdown_slots_retired[ctx][cpu]);
399
400 if (total_slots)
401 retiring = ret_slots / total_slots;
402 return retiring;
403}
404
405static double td_fe_bound(int ctx, int cpu)
406{
407 double fe_bound = 0;
408 double total_slots = td_total_slots(ctx, cpu);
409 double fetch_bub = avg_stats(&runtime_topdown_fetch_bubbles[ctx][cpu]);
410
411 if (total_slots)
412 fe_bound = fetch_bub / total_slots;
413 return fe_bound;
414}
415
416static double td_be_bound(int ctx, int cpu)
417{
418 double sum = (td_fe_bound(ctx, cpu) +
419 td_bad_spec(ctx, cpu) +
420 td_retiring(ctx, cpu));
421 if (sum == 0)
422 return 0;
423 return sanitize_val(1.0 - sum);
424}
425
305void perf_stat__print_shadow_stats(struct perf_evsel *evsel, 426void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
306 double avg, int cpu, 427 double avg, int cpu,
307 struct perf_stat_output_ctx *out) 428 struct perf_stat_output_ctx *out)
@@ -309,6 +430,7 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
309 void *ctxp = out->ctx; 430 void *ctxp = out->ctx;
310 print_metric_t print_metric = out->print_metric; 431 print_metric_t print_metric = out->print_metric;
311 double total, ratio = 0.0, total2; 432 double total, ratio = 0.0, total2;
433 const char *color = NULL;
312 int ctx = evsel_context(evsel); 434 int ctx = evsel_context(evsel);
313 435
314 if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 436 if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
@@ -452,6 +574,46 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
452 avg / ratio); 574 avg / ratio);
453 else 575 else
454 print_metric(ctxp, NULL, NULL, "CPUs utilized", 0); 576 print_metric(ctxp, NULL, NULL, "CPUs utilized", 0);
577 } else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) {
578 double fe_bound = td_fe_bound(ctx, cpu);
579
580 if (fe_bound > 0.2)
581 color = PERF_COLOR_RED;
582 print_metric(ctxp, color, "%8.1f%%", "frontend bound",
583 fe_bound * 100.);
584 } else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_RETIRED)) {
585 double retiring = td_retiring(ctx, cpu);
586
587 if (retiring > 0.7)
588 color = PERF_COLOR_GREEN;
589 print_metric(ctxp, color, "%8.1f%%", "retiring",
590 retiring * 100.);
591 } else if (perf_stat_evsel__is(evsel, TOPDOWN_RECOVERY_BUBBLES)) {
592 double bad_spec = td_bad_spec(ctx, cpu);
593
594 if (bad_spec > 0.1)
595 color = PERF_COLOR_RED;
596 print_metric(ctxp, color, "%8.1f%%", "bad speculation",
597 bad_spec * 100.);
598 } else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_ISSUED)) {
599 double be_bound = td_be_bound(ctx, cpu);
600 const char *name = "backend bound";
601 static int have_recovery_bubbles = -1;
602
603 /* In case the CPU does not support topdown-recovery-bubbles */
604 if (have_recovery_bubbles < 0)
605 have_recovery_bubbles = pmu_have_event("cpu",
606 "topdown-recovery-bubbles");
607 if (!have_recovery_bubbles)
608 name = "backend bound/bad spec";
609
610 if (be_bound > 0.2)
611 color = PERF_COLOR_RED;
612 if (td_total_slots(ctx, cpu) > 0)
613 print_metric(ctxp, color, "%8.1f%%", name,
614 be_bound * 100.);
615 else
616 print_metric(ctxp, NULL, NULL, name, 0);
455 } else if (runtime_nsecs_stats[cpu].n != 0) { 617 } else if (runtime_nsecs_stats[cpu].n != 0) {
456 char unit = 'M'; 618 char unit = 'M';
457 char unit_buf[10]; 619 char unit_buf[10];
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index ffa1d0653861..39345c2ddfc2 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -79,6 +79,11 @@ static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
79 ID(TRANSACTION_START, cpu/tx-start/), 79 ID(TRANSACTION_START, cpu/tx-start/),
80 ID(ELISION_START, cpu/el-start/), 80 ID(ELISION_START, cpu/el-start/),
81 ID(CYCLES_IN_TX_CP, cpu/cycles-ct/), 81 ID(CYCLES_IN_TX_CP, cpu/cycles-ct/),
82 ID(TOPDOWN_TOTAL_SLOTS, topdown-total-slots),
83 ID(TOPDOWN_SLOTS_ISSUED, topdown-slots-issued),
84 ID(TOPDOWN_SLOTS_RETIRED, topdown-slots-retired),
85 ID(TOPDOWN_FETCH_BUBBLES, topdown-fetch-bubbles),
86 ID(TOPDOWN_RECOVERY_BUBBLES, topdown-recovery-bubbles),
82}; 87};
83#undef ID 88#undef ID
84 89
@@ -157,7 +162,7 @@ int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
157{ 162{
158 struct perf_evsel *evsel; 163 struct perf_evsel *evsel;
159 164
160 evlist__for_each(evlist, evsel) { 165 evlist__for_each_entry(evlist, evsel) {
161 if (perf_evsel__alloc_stats(evsel, alloc_raw)) 166 if (perf_evsel__alloc_stats(evsel, alloc_raw))
162 goto out_free; 167 goto out_free;
163 } 168 }
@@ -173,7 +178,7 @@ void perf_evlist__free_stats(struct perf_evlist *evlist)
173{ 178{
174 struct perf_evsel *evsel; 179 struct perf_evsel *evsel;
175 180
176 evlist__for_each(evlist, evsel) { 181 evlist__for_each_entry(evlist, evsel) {
177 perf_evsel__free_stat_priv(evsel); 182 perf_evsel__free_stat_priv(evsel);
178 perf_evsel__free_counts(evsel); 183 perf_evsel__free_counts(evsel);
179 perf_evsel__free_prev_raw_counts(evsel); 184 perf_evsel__free_prev_raw_counts(evsel);
@@ -184,7 +189,7 @@ void perf_evlist__reset_stats(struct perf_evlist *evlist)
184{ 189{
185 struct perf_evsel *evsel; 190 struct perf_evsel *evsel;
186 191
187 evlist__for_each(evlist, evsel) { 192 evlist__for_each_entry(evlist, evsel) {
188 perf_evsel__reset_stat_priv(evsel); 193 perf_evsel__reset_stat_priv(evsel);
189 perf_evsel__reset_counts(evsel); 194 perf_evsel__reset_counts(evsel);
190 } 195 }
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 0150e786ccc7..c29bb94c48a4 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -17,6 +17,11 @@ enum perf_stat_evsel_id {
17 PERF_STAT_EVSEL_ID__TRANSACTION_START, 17 PERF_STAT_EVSEL_ID__TRANSACTION_START,
18 PERF_STAT_EVSEL_ID__ELISION_START, 18 PERF_STAT_EVSEL_ID__ELISION_START,
19 PERF_STAT_EVSEL_ID__CYCLES_IN_TX_CP, 19 PERF_STAT_EVSEL_ID__CYCLES_IN_TX_CP,
20 PERF_STAT_EVSEL_ID__TOPDOWN_TOTAL_SLOTS,
21 PERF_STAT_EVSEL_ID__TOPDOWN_SLOTS_ISSUED,
22 PERF_STAT_EVSEL_ID__TOPDOWN_SLOTS_RETIRED,
23 PERF_STAT_EVSEL_ID__TOPDOWN_FETCH_BUBBLES,
24 PERF_STAT_EVSEL_ID__TOPDOWN_RECOVERY_BUBBLES,
20 PERF_STAT_EVSEL_ID__MAX, 25 PERF_STAT_EVSEL_ID__MAX,
21}; 26};
22 27
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index f95f682aa2b2..817593908d47 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -1,5 +1,5 @@
1#include "debug.h" 1#include "debug.h"
2#include "cache.h" 2#include "util.h"
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4 4
5int prefixcmp(const char *str, const char *prefix) 5int prefixcmp(const char *str, const char *prefix)
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index 54b409297d4a..b268a6648a5d 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -40,6 +40,9 @@
40 40
41#include <assert.h> 41#include <assert.h>
42#include <stdarg.h> 42#include <stdarg.h>
43#include <stddef.h>
44#include <string.h>
45#include <sys/types.h>
43 46
44extern char strbuf_slopbuf[]; 47extern char strbuf_slopbuf[];
45struct strbuf { 48struct strbuf {
diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h
index ca990029e243..19207e50fce5 100644
--- a/tools/perf/util/strlist.h
+++ b/tools/perf/util/strlist.h
@@ -73,7 +73,7 @@ static inline struct str_node *strlist__next(struct str_node *sn)
73 * @pos: the &struct str_node to use as a loop cursor. 73 * @pos: the &struct str_node to use as a loop cursor.
74 * @slist: the &struct strlist for loop. 74 * @slist: the &struct strlist for loop.
75 */ 75 */
76#define strlist__for_each(pos, slist) \ 76#define strlist__for_each_entry(pos, slist) \
77 for (pos = strlist__first(slist); pos; pos = strlist__next(pos)) 77 for (pos = strlist__first(slist); pos; pos = strlist__next(pos))
78 78
79/** 79/**
@@ -83,7 +83,7 @@ static inline struct str_node *strlist__next(struct str_node *sn)
83 * @n: another &struct str_node to use as temporary storage. 83 * @n: another &struct str_node to use as temporary storage.
84 * @slist: the &struct strlist for loop. 84 * @slist: the &struct strlist for loop.
85 */ 85 */
86#define strlist__for_each_safe(pos, n, slist) \ 86#define strlist__for_each_entry_safe(pos, n, slist) \
87 for (pos = strlist__first(slist), n = strlist__next(pos); pos;\ 87 for (pos = strlist__first(slist), n = strlist__next(pos); pos;\
88 pos = n, n = strlist__next(n)) 88 pos = n, n = strlist__next(n))
89#endif /* __PERF_STRLIST_H */ 89#endif /* __PERF_STRLIST_H */
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 87a297dd8901..a34321e9b44d 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -7,6 +7,7 @@
7 7
8#include "symbol.h" 8#include "symbol.h"
9#include "demangle-java.h" 9#include "demangle-java.h"
10#include "demangle-rust.h"
10#include "machine.h" 11#include "machine.h"
11#include "vdso.h" 12#include "vdso.h"
12#include <symbol/kallsyms.h> 13#include <symbol/kallsyms.h>
@@ -16,6 +17,7 @@
16#define EM_AARCH64 183 /* ARM 64 bit */ 17#define EM_AARCH64 183 /* ARM 64 bit */
17#endif 18#endif
18 19
20typedef Elf64_Nhdr GElf_Nhdr;
19 21
20#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT 22#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
21extern char *cplus_demangle(const char *, int); 23extern char *cplus_demangle(const char *, int);
@@ -54,6 +56,14 @@ static int elf_getphdrnum(Elf *elf, size_t *dst)
54} 56}
55#endif 57#endif
56 58
59#ifndef HAVE_ELF_GETSHDRSTRNDX_SUPPORT
60static int elf_getshdrstrndx(Elf *elf __maybe_unused, size_t *dst __maybe_unused)
61{
62 pr_err("%s: update your libelf to > 0.140, this one lacks elf_getshdrstrndx().\n", __func__);
63 return -1;
64}
65#endif
66
57#ifndef NT_GNU_BUILD_ID 67#ifndef NT_GNU_BUILD_ID
58#define NT_GNU_BUILD_ID 3 68#define NT_GNU_BUILD_ID 3
59#endif 69#endif
@@ -1072,6 +1082,13 @@ new_symbol:
1072 demangled = bfd_demangle(NULL, elf_name, demangle_flags); 1082 demangled = bfd_demangle(NULL, elf_name, demangle_flags);
1073 if (demangled == NULL) 1083 if (demangled == NULL)
1074 demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET); 1084 demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET);
1085 else if (rust_is_mangled(demangled))
1086 /*
1087 * Input to Rust demangling is the BFD-demangled
1088 * name which it Rust-demangles in place.
1089 */
1090 rust_demangle_sym(demangled);
1091
1075 if (demangled != NULL) 1092 if (demangled != NULL)
1076 elf_name = demangled; 1093 elf_name = demangled;
1077 } 1094 }
@@ -1781,6 +1798,260 @@ void kcore_extract__delete(struct kcore_extract *kce)
1781 unlink(kce->extract_filename); 1798 unlink(kce->extract_filename);
1782} 1799}
1783 1800
1801#ifdef HAVE_GELF_GETNOTE_SUPPORT
1802/**
1803 * populate_sdt_note : Parse raw data and identify SDT note
1804 * @elf: elf of the opened file
1805 * @data: raw data of a section with description offset applied
1806 * @len: note description size
1807 * @type: type of the note
1808 * @sdt_notes: List to add the SDT note
1809 *
1810 * Responsible for parsing the @data in section .note.stapsdt in @elf and
1811 * if its an SDT note, it appends to @sdt_notes list.
1812 */
1813static int populate_sdt_note(Elf **elf, const char *data, size_t len,
1814 struct list_head *sdt_notes)
1815{
1816 const char *provider, *name;
1817 struct sdt_note *tmp = NULL;
1818 GElf_Ehdr ehdr;
1819 GElf_Addr base_off = 0;
1820 GElf_Shdr shdr;
1821 int ret = -EINVAL;
1822
1823 union {
1824 Elf64_Addr a64[NR_ADDR];
1825 Elf32_Addr a32[NR_ADDR];
1826 } buf;
1827
1828 Elf_Data dst = {
1829 .d_buf = &buf, .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
1830 .d_size = gelf_fsize((*elf), ELF_T_ADDR, NR_ADDR, EV_CURRENT),
1831 .d_off = 0, .d_align = 0
1832 };
1833 Elf_Data src = {
1834 .d_buf = (void *) data, .d_type = ELF_T_ADDR,
1835 .d_version = EV_CURRENT, .d_size = dst.d_size, .d_off = 0,
1836 .d_align = 0
1837 };
1838
1839 tmp = (struct sdt_note *)calloc(1, sizeof(struct sdt_note));
1840 if (!tmp) {
1841 ret = -ENOMEM;
1842 goto out_err;
1843 }
1844
1845 INIT_LIST_HEAD(&tmp->note_list);
1846
1847 if (len < dst.d_size + 3)
1848 goto out_free_note;
1849
1850 /* Translation from file representation to memory representation */
1851 if (gelf_xlatetom(*elf, &dst, &src,
1852 elf_getident(*elf, NULL)[EI_DATA]) == NULL) {
1853 pr_err("gelf_xlatetom : %s\n", elf_errmsg(-1));
1854 goto out_free_note;
1855 }
1856
1857 /* Populate the fields of sdt_note */
1858 provider = data + dst.d_size;
1859
1860 name = (const char *)memchr(provider, '\0', data + len - provider);
1861 if (name++ == NULL)
1862 goto out_free_note;
1863
1864 tmp->provider = strdup(provider);
1865 if (!tmp->provider) {
1866 ret = -ENOMEM;
1867 goto out_free_note;
1868 }
1869 tmp->name = strdup(name);
1870 if (!tmp->name) {
1871 ret = -ENOMEM;
1872 goto out_free_prov;
1873 }
1874
1875 if (gelf_getclass(*elf) == ELFCLASS32) {
1876 memcpy(&tmp->addr, &buf, 3 * sizeof(Elf32_Addr));
1877 tmp->bit32 = true;
1878 } else {
1879 memcpy(&tmp->addr, &buf, 3 * sizeof(Elf64_Addr));
1880 tmp->bit32 = false;
1881 }
1882
1883 if (!gelf_getehdr(*elf, &ehdr)) {
1884 pr_debug("%s : cannot get elf header.\n", __func__);
1885 ret = -EBADF;
1886 goto out_free_name;
1887 }
1888
1889 /* Adjust the prelink effect :
1890 * Find out the .stapsdt.base section.
1891 * This scn will help us to handle prelinking (if present).
1892 * Compare the retrieved file offset of the base section with the
1893 * base address in the description of the SDT note. If its different,
1894 * then accordingly, adjust the note location.
1895 */
1896 if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL)) {
1897 base_off = shdr.sh_offset;
1898 if (base_off) {
1899 if (tmp->bit32)
1900 tmp->addr.a32[0] = tmp->addr.a32[0] + base_off -
1901 tmp->addr.a32[1];
1902 else
1903 tmp->addr.a64[0] = tmp->addr.a64[0] + base_off -
1904 tmp->addr.a64[1];
1905 }
1906 }
1907
1908 list_add_tail(&tmp->note_list, sdt_notes);
1909 return 0;
1910
1911out_free_name:
1912 free(tmp->name);
1913out_free_prov:
1914 free(tmp->provider);
1915out_free_note:
1916 free(tmp);
1917out_err:
1918 return ret;
1919}
1920
1921/**
1922 * construct_sdt_notes_list : constructs a list of SDT notes
1923 * @elf : elf to look into
1924 * @sdt_notes : empty list_head
1925 *
1926 * Scans the sections in 'elf' for the section
1927 * .note.stapsdt. It, then calls populate_sdt_note to find
1928 * out the SDT events and populates the 'sdt_notes'.
1929 */
1930static int construct_sdt_notes_list(Elf *elf, struct list_head *sdt_notes)
1931{
1932 GElf_Ehdr ehdr;
1933 Elf_Scn *scn = NULL;
1934 Elf_Data *data;
1935 GElf_Shdr shdr;
1936 size_t shstrndx, next;
1937 GElf_Nhdr nhdr;
1938 size_t name_off, desc_off, offset;
1939 int ret = 0;
1940
1941 if (gelf_getehdr(elf, &ehdr) == NULL) {
1942 ret = -EBADF;
1943 goto out_ret;
1944 }
1945 if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
1946 ret = -EBADF;
1947 goto out_ret;
1948 }
1949
1950 /* Look for the required section */
1951 scn = elf_section_by_name(elf, &ehdr, &shdr, SDT_NOTE_SCN, NULL);
1952 if (!scn) {
1953 ret = -ENOENT;
1954 goto out_ret;
1955 }
1956
1957 if ((shdr.sh_type != SHT_NOTE) || (shdr.sh_flags & SHF_ALLOC)) {
1958 ret = -ENOENT;
1959 goto out_ret;
1960 }
1961
1962 data = elf_getdata(scn, NULL);
1963
1964 /* Get the SDT notes */
1965 for (offset = 0; (next = gelf_getnote(data, offset, &nhdr, &name_off,
1966 &desc_off)) > 0; offset = next) {
1967 if (nhdr.n_namesz == sizeof(SDT_NOTE_NAME) &&
1968 !memcmp(data->d_buf + name_off, SDT_NOTE_NAME,
1969 sizeof(SDT_NOTE_NAME))) {
1970 /* Check the type of the note */
1971 if (nhdr.n_type != SDT_NOTE_TYPE)
1972 goto out_ret;
1973
1974 ret = populate_sdt_note(&elf, ((data->d_buf) + desc_off),
1975 nhdr.n_descsz, sdt_notes);
1976 if (ret < 0)
1977 goto out_ret;
1978 }
1979 }
1980 if (list_empty(sdt_notes))
1981 ret = -ENOENT;
1982
1983out_ret:
1984 return ret;
1985}
1986
1987/**
1988 * get_sdt_note_list : Wrapper to construct a list of sdt notes
1989 * @head : empty list_head
1990 * @target : file to find SDT notes from
1991 *
1992 * This opens the file, initializes
1993 * the ELF and then calls construct_sdt_notes_list.
1994 */
1995int get_sdt_note_list(struct list_head *head, const char *target)
1996{
1997 Elf *elf;
1998 int fd, ret;
1999
2000 fd = open(target, O_RDONLY);
2001 if (fd < 0)
2002 return -EBADF;
2003
2004 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
2005 if (!elf) {
2006 ret = -EBADF;
2007 goto out_close;
2008 }
2009 ret = construct_sdt_notes_list(elf, head);
2010 elf_end(elf);
2011out_close:
2012 close(fd);
2013 return ret;
2014}
2015
2016/**
2017 * cleanup_sdt_note_list : free the sdt notes' list
2018 * @sdt_notes: sdt notes' list
2019 *
2020 * Free up the SDT notes in @sdt_notes.
2021 * Returns the number of SDT notes free'd.
2022 */
2023int cleanup_sdt_note_list(struct list_head *sdt_notes)
2024{
2025 struct sdt_note *tmp, *pos;
2026 int nr_free = 0;
2027
2028 list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) {
2029 list_del(&pos->note_list);
2030 free(pos->name);
2031 free(pos->provider);
2032 free(pos);
2033 nr_free++;
2034 }
2035 return nr_free;
2036}
2037
2038/**
2039 * sdt_notes__get_count: Counts the number of sdt events
2040 * @start: list_head to sdt_notes list
2041 *
2042 * Returns the number of SDT notes in a list
2043 */
2044int sdt_notes__get_count(struct list_head *start)
2045{
2046 struct sdt_note *sdt_ptr;
2047 int count = 0;
2048
2049 list_for_each_entry(sdt_ptr, start, note_list)
2050 count++;
2051 return count;
2052}
2053#endif
2054
1784void symbol__elf_init(void) 2055void symbol__elf_init(void)
1785{ 2056{
1786 elf_version(EV_CURRENT); 2057 elf_version(EV_CURRENT);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 54c4ff2b1cee..37e8d20ae03e 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1430,7 +1430,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1430 * Read the build id if possible. This is required for 1430 * Read the build id if possible. This is required for
1431 * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work 1431 * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work
1432 */ 1432 */
1433 if (is_regular_file(name) && 1433 if (is_regular_file(dso->long_name) &&
1434 filename__read_build_id(dso->long_name, build_id, BUILD_ID_SIZE) > 0) 1434 filename__read_build_id(dso->long_name, build_id, BUILD_ID_SIZE) > 0)
1435 dso__set_build_id(dso, build_id); 1435 dso__set_build_id(dso, build_id);
1436 1436
@@ -1626,7 +1626,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
1626 if (!dirs) 1626 if (!dirs)
1627 return -1; 1627 return -1;
1628 1628
1629 strlist__for_each(nd, dirs) { 1629 strlist__for_each_entry(nd, dirs) {
1630 scnprintf(kallsyms_filename, sizeof(kallsyms_filename), 1630 scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
1631 "%s/%s/kallsyms", dir, nd->s); 1631 "%s/%s/kallsyms", dir, nd->s);
1632 if (!validate_kcore_addresses(kallsyms_filename, map)) { 1632 if (!validate_kcore_addresses(kallsyms_filename, map)) {
@@ -1641,6 +1641,20 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
1641 return ret; 1641 return ret;
1642} 1642}
1643 1643
1644/*
1645 * Use open(O_RDONLY) to check readability directly instead of access(R_OK)
1646 * since access(R_OK) only checks with real UID/GID but open() use effective
1647 * UID/GID and actual capabilities (e.g. /proc/kcore requires CAP_SYS_RAWIO).
1648 */
1649static bool filename__readable(const char *file)
1650{
1651 int fd = open(file, O_RDONLY);
1652 if (fd < 0)
1653 return false;
1654 close(fd);
1655 return true;
1656}
1657
1644static char *dso__find_kallsyms(struct dso *dso, struct map *map) 1658static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1645{ 1659{
1646 u8 host_build_id[BUILD_ID_SIZE]; 1660 u8 host_build_id[BUILD_ID_SIZE];
@@ -1660,58 +1674,43 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1660 sizeof(host_build_id)) == 0) 1674 sizeof(host_build_id)) == 0)
1661 is_host = dso__build_id_equal(dso, host_build_id); 1675 is_host = dso__build_id_equal(dso, host_build_id);
1662 1676
1663 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); 1677 /* Try a fast path for /proc/kallsyms if possible */
1664
1665 scnprintf(path, sizeof(path), "%s/%s/%s", buildid_dir,
1666 DSO__NAME_KCORE, sbuild_id);
1667
1668 /* Use /proc/kallsyms if possible */
1669 if (is_host) { 1678 if (is_host) {
1670 DIR *d;
1671 int fd;
1672
1673 /* If no cached kcore go with /proc/kallsyms */
1674 d = opendir(path);
1675 if (!d)
1676 goto proc_kallsyms;
1677 closedir(d);
1678
1679 /* 1679 /*
1680 * Do not check the build-id cache, until we know we cannot use 1680 * Do not check the build-id cache, unless we know we cannot use
1681 * /proc/kcore. 1681 * /proc/kcore or module maps don't match to /proc/kallsyms.
1682 * To check readability of /proc/kcore, do not use access(R_OK)
1683 * since /proc/kcore requires CAP_SYS_RAWIO to read and access
1684 * can't check it.
1682 */ 1685 */
1683 fd = open("/proc/kcore", O_RDONLY); 1686 if (filename__readable("/proc/kcore") &&
1684 if (fd != -1) { 1687 !validate_kcore_addresses("/proc/kallsyms", map))
1685 close(fd); 1688 goto proc_kallsyms;
1686 /* If module maps match go with /proc/kallsyms */
1687 if (!validate_kcore_addresses("/proc/kallsyms", map))
1688 goto proc_kallsyms;
1689 }
1690
1691 /* Find kallsyms in build-id cache with kcore */
1692 if (!find_matching_kcore(map, path, sizeof(path)))
1693 return strdup(path);
1694
1695 goto proc_kallsyms;
1696 } 1689 }
1697 1690
1691 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
1692
1698 /* Find kallsyms in build-id cache with kcore */ 1693 /* Find kallsyms in build-id cache with kcore */
1694 scnprintf(path, sizeof(path), "%s/%s/%s",
1695 buildid_dir, DSO__NAME_KCORE, sbuild_id);
1696
1699 if (!find_matching_kcore(map, path, sizeof(path))) 1697 if (!find_matching_kcore(map, path, sizeof(path)))
1700 return strdup(path); 1698 return strdup(path);
1701 1699
1702 scnprintf(path, sizeof(path), "%s/%s/%s", 1700 /* Use current /proc/kallsyms if possible */
1703 buildid_dir, DSO__NAME_KALLSYMS, sbuild_id); 1701 if (is_host) {
1702proc_kallsyms:
1703 return strdup("/proc/kallsyms");
1704 }
1704 1705
1705 if (access(path, F_OK)) { 1706 /* Finally, find a cache of kallsyms */
1707 if (!build_id_cache__kallsyms_path(sbuild_id, path, sizeof(path))) {
1706 pr_err("No kallsyms or vmlinux with build-id %s was found\n", 1708 pr_err("No kallsyms or vmlinux with build-id %s was found\n",
1707 sbuild_id); 1709 sbuild_id);
1708 return NULL; 1710 return NULL;
1709 } 1711 }
1710 1712
1711 return strdup(path); 1713 return strdup(path);
1712
1713proc_kallsyms:
1714 return strdup("/proc/kallsyms");
1715} 1714}
1716 1715
1717static int dso__load_kernel_sym(struct dso *dso, struct map *map, 1716static int dso__load_kernel_sym(struct dso *dso, struct map *map,
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index b10d558a8803..699f7cbcfe72 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -342,4 +342,26 @@ void arch__sym_update(struct symbol *s, GElf_Sym *sym);
342 342
343int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); 343int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb);
344 344
345/* structure containing an SDT note's info */
346struct sdt_note {
347 char *name; /* name of the note*/
348 char *provider; /* provider name */
349 bool bit32; /* whether the location is 32 bits? */
350 union { /* location, base and semaphore addrs */
351 Elf64_Addr a64[3];
352 Elf32_Addr a32[3];
353 } addr;
354 struct list_head note_list; /* SDT notes' list */
355};
356
357int get_sdt_note_list(struct list_head *head, const char *target);
358int cleanup_sdt_note_list(struct list_head *sdt_notes);
359int sdt_notes__get_count(struct list_head *start);
360
361#define SDT_BASE_SCN ".stapsdt.base"
362#define SDT_NOTE_SCN ".note.stapsdt"
363#define SDT_NOTE_TYPE 3
364#define SDT_NOTE_NAME "stapsdt"
365#define NR_ADDR 3
366
345#endif /* __PERF_SYMBOL */ 367#endif /* __PERF_SYMBOL */
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c
index a53603b27e52..8cdcf4641c51 100644
--- a/tools/perf/util/target.c
+++ b/tools/perf/util/target.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include "target.h" 9#include "target.h"
10#include "util.h"
10#include "debug.h" 11#include "debug.h"
11 12
12#include <pwd.h> 13#include <pwd.h>
@@ -121,7 +122,7 @@ int target__strerror(struct target *target, int errnum,
121 BUG_ON(buflen == 0); 122 BUG_ON(buflen == 0);
122 123
123 if (errnum >= 0) { 124 if (errnum >= 0) {
124 const char *err = strerror_r(errnum, buf, buflen); 125 const char *err = str_error_r(errnum, buf, buflen);
125 126
126 if (err != buf) 127 if (err != buf)
127 scnprintf(buf, buflen, "%s", err); 128 scnprintf(buf, buflen, "%s", err);
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
index 825086aa9a08..d3301529f6a7 100644
--- a/tools/perf/util/thread-stack.c
+++ b/tools/perf/util/thread-stack.c
@@ -616,3 +616,10 @@ int thread_stack__process(struct thread *thread, struct comm *comm,
616 616
617 return err; 617 return err;
618} 618}
619
620size_t thread_stack__depth(struct thread *thread)
621{
622 if (!thread->ts)
623 return 0;
624 return thread->ts->cnt;
625}
diff --git a/tools/perf/util/thread-stack.h b/tools/perf/util/thread-stack.h
index ad44c7944b8e..b7e41c4ebfdd 100644
--- a/tools/perf/util/thread-stack.h
+++ b/tools/perf/util/thread-stack.h
@@ -87,6 +87,7 @@ void thread_stack__sample(struct thread *thread, struct ip_callchain *chain,
87 size_t sz, u64 ip); 87 size_t sz, u64 ip);
88int thread_stack__flush(struct thread *thread); 88int thread_stack__flush(struct thread *thread);
89void thread_stack__free(struct thread *thread); 89void thread_stack__free(struct thread *thread);
90size_t thread_stack__depth(struct thread *thread);
90 91
91struct call_return_processor * 92struct call_return_processor *
92call_return_processor__new(int (*process)(struct call_return *cr, void *data), 93call_return_processor__new(int (*process)(struct call_return *cr, void *data),
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 45fcb715a36b..8b10a55410a2 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -43,9 +43,6 @@ struct thread *thread__new(pid_t pid, pid_t tid)
43 thread->cpu = -1; 43 thread->cpu = -1;
44 INIT_LIST_HEAD(&thread->comm_list); 44 INIT_LIST_HEAD(&thread->comm_list);
45 45
46 if (unwind__prepare_access(thread) < 0)
47 goto err_thread;
48
49 comm_str = malloc(32); 46 comm_str = malloc(32);
50 if (!comm_str) 47 if (!comm_str)
51 goto err_thread; 48 goto err_thread;
@@ -201,10 +198,51 @@ size_t thread__fprintf(struct thread *thread, FILE *fp)
201 map_groups__fprintf(thread->mg, fp); 198 map_groups__fprintf(thread->mg, fp);
202} 199}
203 200
204void thread__insert_map(struct thread *thread, struct map *map) 201int thread__insert_map(struct thread *thread, struct map *map)
205{ 202{
203 int ret;
204
205 ret = unwind__prepare_access(thread, map, NULL);
206 if (ret)
207 return ret;
208
206 map_groups__fixup_overlappings(thread->mg, map, stderr); 209 map_groups__fixup_overlappings(thread->mg, map, stderr);
207 map_groups__insert(thread->mg, map); 210 map_groups__insert(thread->mg, map);
211
212 return 0;
213}
214
215static int __thread__prepare_access(struct thread *thread)
216{
217 bool initialized = false;
218 int i, err = 0;
219
220 for (i = 0; i < MAP__NR_TYPES; ++i) {
221 struct maps *maps = &thread->mg->maps[i];
222 struct map *map;
223
224 pthread_rwlock_rdlock(&maps->lock);
225
226 for (map = maps__first(maps); map; map = map__next(map)) {
227 err = unwind__prepare_access(thread, map, &initialized);
228 if (err || initialized)
229 break;
230 }
231
232 pthread_rwlock_unlock(&maps->lock);
233 }
234
235 return err;
236}
237
238static int thread__prepare_access(struct thread *thread)
239{
240 int err = 0;
241
242 if (symbol_conf.use_callchain)
243 err = __thread__prepare_access(thread);
244
245 return err;
208} 246}
209 247
210static int thread__clone_map_groups(struct thread *thread, 248static int thread__clone_map_groups(struct thread *thread,
@@ -214,7 +252,7 @@ static int thread__clone_map_groups(struct thread *thread,
214 252
215 /* This is new thread, we share map groups for process. */ 253 /* This is new thread, we share map groups for process. */
216 if (thread->pid_ == parent->pid_) 254 if (thread->pid_ == parent->pid_)
217 return 0; 255 return thread__prepare_access(thread);
218 256
219 if (thread->mg == parent->mg) { 257 if (thread->mg == parent->mg) {
220 pr_debug("broken map groups on thread %d/%d parent %d/%d\n", 258 pr_debug("broken map groups on thread %d/%d parent %d/%d\n",
@@ -224,7 +262,7 @@ static int thread__clone_map_groups(struct thread *thread,
224 262
225 /* But this one is new process, copy maps. */ 263 /* But this one is new process, copy maps. */
226 for (i = 0; i < MAP__NR_TYPES; ++i) 264 for (i = 0; i < MAP__NR_TYPES; ++i)
227 if (map_groups__clone(thread->mg, parent->mg, i) < 0) 265 if (map_groups__clone(thread, parent->mg, i) < 0)
228 return -ENOMEM; 266 return -ENOMEM;
229 267
230 return 0; 268 return 0;
@@ -265,3 +303,14 @@ void thread__find_cpumode_addr_location(struct thread *thread,
265 break; 303 break;
266 } 304 }
267} 305}
306
307struct thread *thread__main_thread(struct machine *machine, struct thread *thread)
308{
309 if (thread->pid_ == thread->tid)
310 return thread__get(thread);
311
312 if (thread->pid_ == -1)
313 return NULL;
314
315 return machine__find_thread(machine, thread->pid_, thread->pid_);
316}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 45fba13c800b..99263cb6e6b6 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -9,11 +9,9 @@
9#include "symbol.h" 9#include "symbol.h"
10#include <strlist.h> 10#include <strlist.h>
11#include <intlist.h> 11#include <intlist.h>
12#ifdef HAVE_LIBUNWIND_SUPPORT
13#include <libunwind.h>
14#endif
15 12
16struct thread_stack; 13struct thread_stack;
14struct unwind_libunwind_ops;
17 15
18struct thread { 16struct thread {
19 union { 17 union {
@@ -36,7 +34,8 @@ struct thread {
36 void *priv; 34 void *priv;
37 struct thread_stack *ts; 35 struct thread_stack *ts;
38#ifdef HAVE_LIBUNWIND_SUPPORT 36#ifdef HAVE_LIBUNWIND_SUPPORT
39 unw_addr_space_t addr_space; 37 void *addr_space;
38 struct unwind_libunwind_ops *unwind_libunwind_ops;
40#endif 39#endif
41}; 40};
42 41
@@ -77,10 +76,12 @@ int thread__comm_len(struct thread *thread);
77struct comm *thread__comm(const struct thread *thread); 76struct comm *thread__comm(const struct thread *thread);
78struct comm *thread__exec_comm(const struct thread *thread); 77struct comm *thread__exec_comm(const struct thread *thread);
79const char *thread__comm_str(const struct thread *thread); 78const char *thread__comm_str(const struct thread *thread);
80void thread__insert_map(struct thread *thread, struct map *map); 79int thread__insert_map(struct thread *thread, struct map *map);
81int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp); 80int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
82size_t thread__fprintf(struct thread *thread, FILE *fp); 81size_t thread__fprintf(struct thread *thread, FILE *fp);
83 82
83struct thread *thread__main_thread(struct machine *machine, struct thread *thread);
84
84void thread__find_addr_map(struct thread *thread, 85void thread__find_addr_map(struct thread *thread,
85 u8 cpumode, enum map_type type, u64 addr, 86 u8 cpumode, enum map_type type, u64 addr,
86 struct addr_location *al); 87 struct addr_location *al);
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 5654fe15e036..40585f5b7027 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -202,7 +202,7 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
202 if (!slist) 202 if (!slist)
203 return NULL; 203 return NULL;
204 204
205 strlist__for_each(pos, slist) { 205 strlist__for_each_entry(pos, slist) {
206 pid = strtol(pos->s, &end_ptr, 10); 206 pid = strtol(pos->s, &end_ptr, 10);
207 207
208 if (pid == INT_MIN || pid == INT_MAX || 208 if (pid == INT_MIN || pid == INT_MAX ||
@@ -278,7 +278,7 @@ struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
278 if (!slist) 278 if (!slist)
279 return NULL; 279 return NULL;
280 280
281 strlist__for_each(pos, slist) { 281 strlist__for_each_entry(pos, slist) {
282 tid = strtol(pos->s, &end_ptr, 10); 282 tid = strtol(pos->s, &end_ptr, 10);
283 283
284 if (tid == INT_MIN || tid == INT_MAX || 284 if (tid == INT_MIN || tid == INT_MAX ||
diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c
index 8ae051e0ec79..c330780674fc 100644
--- a/tools/perf/util/trace-event.c
+++ b/tools/perf/util/trace-event.c
@@ -105,3 +105,11 @@ trace_event__tp_format(const char *sys, const char *name)
105 105
106 return tp_format(sys, name); 106 return tp_format(sys, name);
107} 107}
108
109struct event_format *trace_event__tp_format_id(int id)
110{
111 if (!tevent_initialized && trace_event__init2())
112 return ERR_PTR(-ENOMEM);
113
114 return pevent_find_event(tevent.pevent, id);
115}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index bce5b1dac268..b0af9c81bb0d 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -23,6 +23,8 @@ int trace_event__register_resolver(struct machine *machine,
23struct event_format* 23struct event_format*
24trace_event__tp_format(const char *sys, const char *name); 24trace_event__tp_format(const char *sys, const char *name);
25 25
26struct event_format *trace_event__tp_format_id(int id);
27
26int bigendian(void); 28int bigendian(void);
27 29
28void event_format__fprintf(struct event_format *event, 30void event_format__fprintf(struct event_format *event,
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
new file mode 100644
index 000000000000..97c0f8fc5561
--- /dev/null
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -0,0 +1,699 @@
1/*
2 * Post mortem Dwarf CFI based unwinding on top of regs and stack dumps.
3 *
4 * Lots of this code have been borrowed or heavily inspired from parts of
5 * the libunwind 0.99 code which are (amongst other contributors I may have
6 * forgotten):
7 *
8 * Copyright (C) 2002-2007 Hewlett-Packard Co
9 * Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
10 *
11 * And the bugs have been added by:
12 *
13 * Copyright (C) 2010, Frederic Weisbecker <fweisbec@gmail.com>
14 * Copyright (C) 2012, Jiri Olsa <jolsa@redhat.com>
15 *
16 */
17
18#include <elf.h>
19#include <gelf.h>
20#include <fcntl.h>
21#include <string.h>
22#include <unistd.h>
23#include <sys/mman.h>
24#include <linux/list.h>
25#ifndef REMOTE_UNWIND_LIBUNWIND
26#include <libunwind.h>
27#include <libunwind-ptrace.h>
28#endif
29#include "callchain.h"
30#include "thread.h"
31#include "session.h"
32#include "perf_regs.h"
33#include "unwind.h"
34#include "symbol.h"
35#include "util.h"
36#include "debug.h"
37#include "asm/bug.h"
38
39extern int
40UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
41 unw_word_t ip,
42 unw_dyn_info_t *di,
43 unw_proc_info_t *pi,
44 int need_unwind_info, void *arg);
45
46#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
47
48extern int
49UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
50 unw_word_t ip,
51 unw_word_t segbase,
52 const char *obj_name, unw_word_t start,
53 unw_word_t end);
54
55#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
56
57#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
58#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
59
60/* Pointer-encoding formats: */
61#define DW_EH_PE_omit 0xff
62#define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */
63#define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */
64#define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */
65#define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */
66#define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */
67
68/* Pointer-encoding application: */
69#define DW_EH_PE_absptr 0x00 /* absolute value */
70#define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */
71
72/*
73 * The following are not documented by LSB v1.3, yet they are used by
74 * GCC, presumably they aren't documented by LSB since they aren't
75 * used on Linux:
76 */
77#define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */
78#define DW_EH_PE_aligned 0x50 /* aligned pointer */
79
80/* Flags intentionaly not handled, since they're not needed:
81 * #define DW_EH_PE_indirect 0x80
82 * #define DW_EH_PE_uleb128 0x01
83 * #define DW_EH_PE_udata2 0x02
84 * #define DW_EH_PE_sleb128 0x09
85 * #define DW_EH_PE_sdata2 0x0a
86 * #define DW_EH_PE_textrel 0x20
87 * #define DW_EH_PE_datarel 0x30
88 */
89
90struct unwind_info {
91 struct perf_sample *sample;
92 struct machine *machine;
93 struct thread *thread;
94};
95
96#define dw_read(ptr, type, end) ({ \
97 type *__p = (type *) ptr; \
98 type __v; \
99 if ((__p + 1) > (type *) end) \
100 return -EINVAL; \
101 __v = *__p++; \
102 ptr = (typeof(ptr)) __p; \
103 __v; \
104 })
105
106static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val,
107 u8 encoding)
108{
109 u8 *cur = *p;
110 *val = 0;
111
112 switch (encoding) {
113 case DW_EH_PE_omit:
114 *val = 0;
115 goto out;
116 case DW_EH_PE_ptr:
117 *val = dw_read(cur, unsigned long, end);
118 goto out;
119 default:
120 break;
121 }
122
123 switch (encoding & DW_EH_PE_APPL_MASK) {
124 case DW_EH_PE_absptr:
125 break;
126 case DW_EH_PE_pcrel:
127 *val = (unsigned long) cur;
128 break;
129 default:
130 return -EINVAL;
131 }
132
133 if ((encoding & 0x07) == 0x00)
134 encoding |= DW_EH_PE_udata4;
135
136 switch (encoding & DW_EH_PE_FORMAT_MASK) {
137 case DW_EH_PE_sdata4:
138 *val += dw_read(cur, s32, end);
139 break;
140 case DW_EH_PE_udata4:
141 *val += dw_read(cur, u32, end);
142 break;
143 case DW_EH_PE_sdata8:
144 *val += dw_read(cur, s64, end);
145 break;
146 case DW_EH_PE_udata8:
147 *val += dw_read(cur, u64, end);
148 break;
149 default:
150 return -EINVAL;
151 }
152
153 out:
154 *p = cur;
155 return 0;
156}
157
158#define dw_read_encoded_value(ptr, end, enc) ({ \
159 u64 __v; \
160 if (__dw_read_encoded_value(&ptr, end, &__v, enc)) { \
161 return -EINVAL; \
162 } \
163 __v; \
164 })
165
166static u64 elf_section_offset(int fd, const char *name)
167{
168 Elf *elf;
169 GElf_Ehdr ehdr;
170 GElf_Shdr shdr;
171 u64 offset = 0;
172
173 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
174 if (elf == NULL)
175 return 0;
176
177 do {
178 if (gelf_getehdr(elf, &ehdr) == NULL)
179 break;
180
181 if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL))
182 break;
183
184 offset = shdr.sh_offset;
185 } while (0);
186
187 elf_end(elf);
188 return offset;
189}
190
191#ifndef NO_LIBUNWIND_DEBUG_FRAME
192static int elf_is_exec(int fd, const char *name)
193{
194 Elf *elf;
195 GElf_Ehdr ehdr;
196 int retval = 0;
197
198 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
199 if (elf == NULL)
200 return 0;
201 if (gelf_getehdr(elf, &ehdr) == NULL)
202 goto out;
203
204 retval = (ehdr.e_type == ET_EXEC);
205
206out:
207 elf_end(elf);
208 pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval);
209 return retval;
210}
211#endif
212
213struct table_entry {
214 u32 start_ip_offset;
215 u32 fde_offset;
216};
217
218struct eh_frame_hdr {
219 unsigned char version;
220 unsigned char eh_frame_ptr_enc;
221 unsigned char fde_count_enc;
222 unsigned char table_enc;
223
224 /*
225 * The rest of the header is variable-length and consists of the
226 * following members:
227 *
228 * encoded_t eh_frame_ptr;
229 * encoded_t fde_count;
230 */
231
232 /* A single encoded pointer should not be more than 8 bytes. */
233 u64 enc[2];
234
235 /*
236 * struct {
237 * encoded_t start_ip;
238 * encoded_t fde_addr;
239 * } binary_search_table[fde_count];
240 */
241 char data[0];
242} __packed;
243
244static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
245 u64 offset, u64 *table_data, u64 *segbase,
246 u64 *fde_count)
247{
248 struct eh_frame_hdr hdr;
249 u8 *enc = (u8 *) &hdr.enc;
250 u8 *end = (u8 *) &hdr.data;
251 ssize_t r;
252
253 r = dso__data_read_offset(dso, machine, offset,
254 (u8 *) &hdr, sizeof(hdr));
255 if (r != sizeof(hdr))
256 return -EINVAL;
257
258 /* We dont need eh_frame_ptr, just skip it. */
259 dw_read_encoded_value(enc, end, hdr.eh_frame_ptr_enc);
260
261 *fde_count = dw_read_encoded_value(enc, end, hdr.fde_count_enc);
262 *segbase = offset;
263 *table_data = (enc - (u8 *) &hdr) + offset;
264 return 0;
265}
266
267static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
268 u64 *table_data, u64 *segbase,
269 u64 *fde_count)
270{
271 int ret = -EINVAL, fd;
272 u64 offset = dso->data.eh_frame_hdr_offset;
273
274 if (offset == 0) {
275 fd = dso__data_get_fd(dso, machine);
276 if (fd < 0)
277 return -EINVAL;
278
279 /* Check the .eh_frame section for unwinding info */
280 offset = elf_section_offset(fd, ".eh_frame_hdr");
281 dso->data.eh_frame_hdr_offset = offset;
282 dso__data_put_fd(dso);
283 }
284
285 if (offset)
286 ret = unwind_spec_ehframe(dso, machine, offset,
287 table_data, segbase,
288 fde_count);
289
290 return ret;
291}
292
293#ifndef NO_LIBUNWIND_DEBUG_FRAME
294static int read_unwind_spec_debug_frame(struct dso *dso,
295 struct machine *machine, u64 *offset)
296{
297 int fd;
298 u64 ofs = dso->data.debug_frame_offset;
299
300 if (ofs == 0) {
301 fd = dso__data_get_fd(dso, machine);
302 if (fd < 0)
303 return -EINVAL;
304
305 /* Check the .debug_frame section for unwinding info */
306 ofs = elf_section_offset(fd, ".debug_frame");
307 dso->data.debug_frame_offset = ofs;
308 dso__data_put_fd(dso);
309 }
310
311 *offset = ofs;
312 if (*offset)
313 return 0;
314
315 return -EINVAL;
316}
317#endif
318
319static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
320{
321 struct addr_location al;
322
323 thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
324 MAP__FUNCTION, ip, &al);
325 if (!al.map) {
326 /*
327 * We've seen cases (softice) where DWARF unwinder went
328 * through non executable mmaps, which we need to lookup
329 * in MAP__VARIABLE tree.
330 */
331 thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
332 MAP__VARIABLE, ip, &al);
333 }
334 return al.map;
335}
336
337static int
338find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
339 int need_unwind_info, void *arg)
340{
341 struct unwind_info *ui = arg;
342 struct map *map;
343 unw_dyn_info_t di;
344 u64 table_data, segbase, fde_count;
345 int ret = -EINVAL;
346
347 map = find_map(ip, ui);
348 if (!map || !map->dso)
349 return -EINVAL;
350
351 pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
352
353 /* Check the .eh_frame section for unwinding info */
354 if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
355 &table_data, &segbase, &fde_count)) {
356 memset(&di, 0, sizeof(di));
357 di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
358 di.start_ip = map->start;
359 di.end_ip = map->end;
360 di.u.rti.segbase = map->start + segbase;
361 di.u.rti.table_data = map->start + table_data;
362 di.u.rti.table_len = fde_count * sizeof(struct table_entry)
363 / sizeof(unw_word_t);
364 ret = dwarf_search_unwind_table(as, ip, &di, pi,
365 need_unwind_info, arg);
366 }
367
368#ifndef NO_LIBUNWIND_DEBUG_FRAME
369 /* Check the .debug_frame section for unwinding info */
370 if (ret < 0 &&
371 !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
372 int fd = dso__data_get_fd(map->dso, ui->machine);
373 int is_exec = elf_is_exec(fd, map->dso->name);
374 unw_word_t base = is_exec ? 0 : map->start;
375 const char *symfile;
376
377 if (fd >= 0)
378 dso__data_put_fd(map->dso);
379
380 symfile = map->dso->symsrc_filename ?: map->dso->name;
381
382 memset(&di, 0, sizeof(di));
383 if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
384 map->start, map->end))
385 return dwarf_search_unwind_table(as, ip, &di, pi,
386 need_unwind_info, arg);
387 }
388#endif
389
390 return ret;
391}
392
393static int access_fpreg(unw_addr_space_t __maybe_unused as,
394 unw_regnum_t __maybe_unused num,
395 unw_fpreg_t __maybe_unused *val,
396 int __maybe_unused __write,
397 void __maybe_unused *arg)
398{
399 pr_err("unwind: access_fpreg unsupported\n");
400 return -UNW_EINVAL;
401}
402
403static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as,
404 unw_word_t __maybe_unused *dil_addr,
405 void __maybe_unused *arg)
406{
407 return -UNW_ENOINFO;
408}
409
410static int resume(unw_addr_space_t __maybe_unused as,
411 unw_cursor_t __maybe_unused *cu,
412 void __maybe_unused *arg)
413{
414 pr_err("unwind: resume unsupported\n");
415 return -UNW_EINVAL;
416}
417
418static int
419get_proc_name(unw_addr_space_t __maybe_unused as,
420 unw_word_t __maybe_unused addr,
421 char __maybe_unused *bufp, size_t __maybe_unused buf_len,
422 unw_word_t __maybe_unused *offp, void __maybe_unused *arg)
423{
424 pr_err("unwind: get_proc_name unsupported\n");
425 return -UNW_EINVAL;
426}
427
428static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
429 unw_word_t *data)
430{
431 struct map *map;
432 ssize_t size;
433
434 map = find_map(addr, ui);
435 if (!map) {
436 pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
437 return -1;
438 }
439
440 if (!map->dso)
441 return -1;
442
443 size = dso__data_read_addr(map->dso, map, ui->machine,
444 addr, (u8 *) data, sizeof(*data));
445
446 return !(size == sizeof(*data));
447}
448
449static int access_mem(unw_addr_space_t __maybe_unused as,
450 unw_word_t addr, unw_word_t *valp,
451 int __write, void *arg)
452{
453 struct unwind_info *ui = arg;
454 struct stack_dump *stack = &ui->sample->user_stack;
455 u64 start, end;
456 int offset;
457 int ret;
458
459 /* Don't support write, probably not needed. */
460 if (__write || !stack || !ui->sample->user_regs.regs) {
461 *valp = 0;
462 return 0;
463 }
464
465 ret = perf_reg_value(&start, &ui->sample->user_regs,
466 LIBUNWIND__ARCH_REG_SP);
467 if (ret)
468 return ret;
469
470 end = start + stack->size;
471
472 /* Check overflow. */
473 if (addr + sizeof(unw_word_t) < addr)
474 return -EINVAL;
475
476 if (addr < start || addr + sizeof(unw_word_t) >= end) {
477 ret = access_dso_mem(ui, addr, valp);
478 if (ret) {
479 pr_debug("unwind: access_mem %p not inside range"
480 " 0x%" PRIx64 "-0x%" PRIx64 "\n",
481 (void *) (uintptr_t) addr, start, end);
482 *valp = 0;
483 return ret;
484 }
485 return 0;
486 }
487
488 offset = addr - start;
489 *valp = *(unw_word_t *)&stack->data[offset];
490 pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
491 (void *) (uintptr_t) addr, (unsigned long)*valp, offset);
492 return 0;
493}
494
495static int access_reg(unw_addr_space_t __maybe_unused as,
496 unw_regnum_t regnum, unw_word_t *valp,
497 int __write, void *arg)
498{
499 struct unwind_info *ui = arg;
500 int id, ret;
501 u64 val;
502
503 /* Don't support write, I suspect we don't need it. */
504 if (__write) {
505 pr_err("unwind: access_reg w %d\n", regnum);
506 return 0;
507 }
508
509 if (!ui->sample->user_regs.regs) {
510 *valp = 0;
511 return 0;
512 }
513
514 id = LIBUNWIND__ARCH_REG_ID(regnum);
515 if (id < 0)
516 return -EINVAL;
517
518 ret = perf_reg_value(&val, &ui->sample->user_regs, id);
519 if (ret) {
520 pr_err("unwind: can't read reg %d\n", regnum);
521 return ret;
522 }
523
524 *valp = (unw_word_t) val;
525 pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp);
526 return 0;
527}
528
529static void put_unwind_info(unw_addr_space_t __maybe_unused as,
530 unw_proc_info_t *pi __maybe_unused,
531 void *arg __maybe_unused)
532{
533 pr_debug("unwind: put_unwind_info called\n");
534}
535
536static int entry(u64 ip, struct thread *thread,
537 unwind_entry_cb_t cb, void *arg)
538{
539 struct unwind_entry e;
540 struct addr_location al;
541
542 thread__find_addr_location(thread, PERF_RECORD_MISC_USER,
543 MAP__FUNCTION, ip, &al);
544
545 e.ip = ip;
546 e.map = al.map;
547 e.sym = al.sym;
548
549 pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
550 al.sym ? al.sym->name : "''",
551 ip,
552 al.map ? al.map->map_ip(al.map, ip) : (u64) 0);
553
554 return cb(&e, arg);
555}
556
557static void display_error(int err)
558{
559 switch (err) {
560 case UNW_EINVAL:
561 pr_err("unwind: Only supports local.\n");
562 break;
563 case UNW_EUNSPEC:
564 pr_err("unwind: Unspecified error.\n");
565 break;
566 case UNW_EBADREG:
567 pr_err("unwind: Register unavailable.\n");
568 break;
569 default:
570 break;
571 }
572}
573
574static unw_accessors_t accessors = {
575 .find_proc_info = find_proc_info,
576 .put_unwind_info = put_unwind_info,
577 .get_dyn_info_list_addr = get_dyn_info_list_addr,
578 .access_mem = access_mem,
579 .access_reg = access_reg,
580 .access_fpreg = access_fpreg,
581 .resume = resume,
582 .get_proc_name = get_proc_name,
583};
584
585static int _unwind__prepare_access(struct thread *thread)
586{
587 if (callchain_param.record_mode != CALLCHAIN_DWARF)
588 return 0;
589
590 thread->addr_space = unw_create_addr_space(&accessors, 0);
591 if (!thread->addr_space) {
592 pr_err("unwind: Can't create unwind address space.\n");
593 return -ENOMEM;
594 }
595
596 unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL);
597 return 0;
598}
599
600static void _unwind__flush_access(struct thread *thread)
601{
602 if (callchain_param.record_mode != CALLCHAIN_DWARF)
603 return;
604
605 unw_flush_cache(thread->addr_space, 0, 0);
606}
607
608static void _unwind__finish_access(struct thread *thread)
609{
610 if (callchain_param.record_mode != CALLCHAIN_DWARF)
611 return;
612
613 unw_destroy_addr_space(thread->addr_space);
614}
615
616static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
617 void *arg, int max_stack)
618{
619 u64 val;
620 unw_word_t ips[max_stack];
621 unw_addr_space_t addr_space;
622 unw_cursor_t c;
623 int ret, i = 0;
624
625 ret = perf_reg_value(&val, &ui->sample->user_regs,
626 LIBUNWIND__ARCH_REG_IP);
627 if (ret)
628 return ret;
629
630 ips[i++] = (unw_word_t) val;
631
632 /*
633 * If we need more than one entry, do the DWARF
634 * unwind itself.
635 */
636 if (max_stack - 1 > 0) {
637 WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
638 addr_space = ui->thread->addr_space;
639
640 if (addr_space == NULL)
641 return -1;
642
643 ret = unw_init_remote(&c, addr_space, ui);
644 if (ret)
645 display_error(ret);
646
647 while (!ret && (unw_step(&c) > 0) && i < max_stack) {
648 unw_get_reg(&c, UNW_REG_IP, &ips[i]);
649 ++i;
650 }
651
652 max_stack = i;
653 }
654
655 /*
656 * Display what we got based on the order setup.
657 */
658 for (i = 0; i < max_stack && !ret; i++) {
659 int j = i;
660
661 if (callchain_param.order == ORDER_CALLER)
662 j = max_stack - i - 1;
663 ret = ips[j] ? entry(ips[j], ui->thread, cb, arg) : 0;
664 }
665
666 return ret;
667}
668
669static int _unwind__get_entries(unwind_entry_cb_t cb, void *arg,
670 struct thread *thread,
671 struct perf_sample *data, int max_stack)
672{
673 struct unwind_info ui = {
674 .sample = data,
675 .thread = thread,
676 .machine = thread->mg->machine,
677 };
678
679 if (!data->user_regs.regs)
680 return -EINVAL;
681
682 if (max_stack <= 0)
683 return -EINVAL;
684
685 return get_entries(&ui, cb, arg, max_stack);
686}
687
688static struct unwind_libunwind_ops
689_unwind_libunwind_ops = {
690 .prepare_access = _unwind__prepare_access,
691 .flush_access = _unwind__flush_access,
692 .finish_access = _unwind__finish_access,
693 .get_entries = _unwind__get_entries,
694};
695
696#ifndef REMOTE_UNWIND_LIBUNWIND
697struct unwind_libunwind_ops *
698local_unwind_libunwind_ops = &_unwind_libunwind_ops;
699#endif
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 63687d3a344e..6d542a4e0648 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -1,682 +1,83 @@
1/* 1#include "unwind.h"
2 * Post mortem Dwarf CFI based unwinding on top of regs and stack dumps.
3 *
4 * Lots of this code have been borrowed or heavily inspired from parts of
5 * the libunwind 0.99 code which are (amongst other contributors I may have
6 * forgotten):
7 *
8 * Copyright (C) 2002-2007 Hewlett-Packard Co
9 * Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
10 *
11 * And the bugs have been added by:
12 *
13 * Copyright (C) 2010, Frederic Weisbecker <fweisbec@gmail.com>
14 * Copyright (C) 2012, Jiri Olsa <jolsa@redhat.com>
15 *
16 */
17
18#include <elf.h>
19#include <gelf.h>
20#include <fcntl.h>
21#include <string.h>
22#include <unistd.h>
23#include <sys/mman.h>
24#include <linux/list.h>
25#include <libunwind.h>
26#include <libunwind-ptrace.h>
27#include "callchain.h"
28#include "thread.h" 2#include "thread.h"
29#include "session.h" 3#include "session.h"
30#include "perf_regs.h"
31#include "unwind.h"
32#include "symbol.h"
33#include "util.h"
34#include "debug.h" 4#include "debug.h"
35#include "asm/bug.h" 5#include "arch/common.h"
36
37extern int
38UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
39 unw_word_t ip,
40 unw_dyn_info_t *di,
41 unw_proc_info_t *pi,
42 int need_unwind_info, void *arg);
43
44#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
45
46extern int
47UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
48 unw_word_t ip,
49 unw_word_t segbase,
50 const char *obj_name, unw_word_t start,
51 unw_word_t end);
52
53#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
54
55#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
56#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
57
58/* Pointer-encoding formats: */
59#define DW_EH_PE_omit 0xff
60#define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */
61#define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */
62#define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */
63#define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */
64#define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */
65
66/* Pointer-encoding application: */
67#define DW_EH_PE_absptr 0x00 /* absolute value */
68#define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */
69
70/*
71 * The following are not documented by LSB v1.3, yet they are used by
72 * GCC, presumably they aren't documented by LSB since they aren't
73 * used on Linux:
74 */
75#define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */
76#define DW_EH_PE_aligned 0x50 /* aligned pointer */
77 6
78/* Flags intentionaly not handled, since they're not needed: 7struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
79 * #define DW_EH_PE_indirect 0x80 8struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops;
80 * #define DW_EH_PE_uleb128 0x01 9struct unwind_libunwind_ops __weak *arm64_unwind_libunwind_ops;
81 * #define DW_EH_PE_udata2 0x02
82 * #define DW_EH_PE_sleb128 0x09
83 * #define DW_EH_PE_sdata2 0x0a
84 * #define DW_EH_PE_textrel 0x20
85 * #define DW_EH_PE_datarel 0x30
86 */
87 10
88struct unwind_info { 11static void unwind__register_ops(struct thread *thread,
89 struct perf_sample *sample; 12 struct unwind_libunwind_ops *ops)
90 struct machine *machine;
91 struct thread *thread;
92};
93
94#define dw_read(ptr, type, end) ({ \
95 type *__p = (type *) ptr; \
96 type __v; \
97 if ((__p + 1) > (type *) end) \
98 return -EINVAL; \
99 __v = *__p++; \
100 ptr = (typeof(ptr)) __p; \
101 __v; \
102 })
103
104static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val,
105 u8 encoding)
106{ 13{
107 u8 *cur = *p; 14 thread->unwind_libunwind_ops = ops;
108 *val = 0;
109
110 switch (encoding) {
111 case DW_EH_PE_omit:
112 *val = 0;
113 goto out;
114 case DW_EH_PE_ptr:
115 *val = dw_read(cur, unsigned long, end);
116 goto out;
117 default:
118 break;
119 }
120
121 switch (encoding & DW_EH_PE_APPL_MASK) {
122 case DW_EH_PE_absptr:
123 break;
124 case DW_EH_PE_pcrel:
125 *val = (unsigned long) cur;
126 break;
127 default:
128 return -EINVAL;
129 }
130
131 if ((encoding & 0x07) == 0x00)
132 encoding |= DW_EH_PE_udata4;
133
134 switch (encoding & DW_EH_PE_FORMAT_MASK) {
135 case DW_EH_PE_sdata4:
136 *val += dw_read(cur, s32, end);
137 break;
138 case DW_EH_PE_udata4:
139 *val += dw_read(cur, u32, end);
140 break;
141 case DW_EH_PE_sdata8:
142 *val += dw_read(cur, s64, end);
143 break;
144 case DW_EH_PE_udata8:
145 *val += dw_read(cur, u64, end);
146 break;
147 default:
148 return -EINVAL;
149 }
150
151 out:
152 *p = cur;
153 return 0;
154}
155
156#define dw_read_encoded_value(ptr, end, enc) ({ \
157 u64 __v; \
158 if (__dw_read_encoded_value(&ptr, end, &__v, enc)) { \
159 return -EINVAL; \
160 } \
161 __v; \
162 })
163
164static u64 elf_section_offset(int fd, const char *name)
165{
166 Elf *elf;
167 GElf_Ehdr ehdr;
168 GElf_Shdr shdr;
169 u64 offset = 0;
170
171 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
172 if (elf == NULL)
173 return 0;
174
175 do {
176 if (gelf_getehdr(elf, &ehdr) == NULL)
177 break;
178
179 if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL))
180 break;
181
182 offset = shdr.sh_offset;
183 } while (0);
184
185 elf_end(elf);
186 return offset;
187} 15}
188 16
189#ifndef NO_LIBUNWIND_DEBUG_FRAME 17int unwind__prepare_access(struct thread *thread, struct map *map,
190static int elf_is_exec(int fd, const char *name) 18 bool *initialized)
191{ 19{
192 Elf *elf; 20 const char *arch;
193 GElf_Ehdr ehdr; 21 enum dso_type dso_type;
194 int retval = 0; 22 struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops;
23 int err;
195 24
196 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 25 if (thread->addr_space) {
197 if (elf == NULL) 26 pr_debug("unwind: thread map already set, dso=%s\n",
27 map->dso->name);
28 if (initialized)
29 *initialized = true;
198 return 0; 30 return 0;
199 if (gelf_getehdr(elf, &ehdr) == NULL)
200 goto out;
201
202 retval = (ehdr.e_type == ET_EXEC);
203
204out:
205 elf_end(elf);
206 pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval);
207 return retval;
208}
209#endif
210
211struct table_entry {
212 u32 start_ip_offset;
213 u32 fde_offset;
214};
215
216struct eh_frame_hdr {
217 unsigned char version;
218 unsigned char eh_frame_ptr_enc;
219 unsigned char fde_count_enc;
220 unsigned char table_enc;
221
222 /*
223 * The rest of the header is variable-length and consists of the
224 * following members:
225 *
226 * encoded_t eh_frame_ptr;
227 * encoded_t fde_count;
228 */
229
230 /* A single encoded pointer should not be more than 8 bytes. */
231 u64 enc[2];
232
233 /*
234 * struct {
235 * encoded_t start_ip;
236 * encoded_t fde_addr;
237 * } binary_search_table[fde_count];
238 */
239 char data[0];
240} __packed;
241
242static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
243 u64 offset, u64 *table_data, u64 *segbase,
244 u64 *fde_count)
245{
246 struct eh_frame_hdr hdr;
247 u8 *enc = (u8 *) &hdr.enc;
248 u8 *end = (u8 *) &hdr.data;
249 ssize_t r;
250
251 r = dso__data_read_offset(dso, machine, offset,
252 (u8 *) &hdr, sizeof(hdr));
253 if (r != sizeof(hdr))
254 return -EINVAL;
255
256 /* We dont need eh_frame_ptr, just skip it. */
257 dw_read_encoded_value(enc, end, hdr.eh_frame_ptr_enc);
258
259 *fde_count = dw_read_encoded_value(enc, end, hdr.fde_count_enc);
260 *segbase = offset;
261 *table_data = (enc - (u8 *) &hdr) + offset;
262 return 0;
263}
264
265static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
266 u64 *table_data, u64 *segbase,
267 u64 *fde_count)
268{
269 int ret = -EINVAL, fd;
270 u64 offset = dso->data.eh_frame_hdr_offset;
271
272 if (offset == 0) {
273 fd = dso__data_get_fd(dso, machine);
274 if (fd < 0)
275 return -EINVAL;
276
277 /* Check the .eh_frame section for unwinding info */
278 offset = elf_section_offset(fd, ".eh_frame_hdr");
279 dso->data.eh_frame_hdr_offset = offset;
280 dso__data_put_fd(dso);
281 } 31 }
282 32
283 if (offset) 33 /* env->arch is NULL for live-mode (i.e. perf top) */
284 ret = unwind_spec_ehframe(dso, machine, offset, 34 if (!thread->mg->machine->env || !thread->mg->machine->env->arch)
285 table_data, segbase, 35 goto out_register;
286 fde_count);
287 36
288 return ret; 37 dso_type = dso__type(map->dso, thread->mg->machine);
289} 38 if (dso_type == DSO__TYPE_UNKNOWN)
290
291#ifndef NO_LIBUNWIND_DEBUG_FRAME
292static int read_unwind_spec_debug_frame(struct dso *dso,
293 struct machine *machine, u64 *offset)
294{
295 int fd;
296 u64 ofs = dso->data.debug_frame_offset;
297
298 if (ofs == 0) {
299 fd = dso__data_get_fd(dso, machine);
300 if (fd < 0)
301 return -EINVAL;
302
303 /* Check the .debug_frame section for unwinding info */
304 ofs = elf_section_offset(fd, ".debug_frame");
305 dso->data.debug_frame_offset = ofs;
306 dso__data_put_fd(dso);
307 }
308
309 *offset = ofs;
310 if (*offset)
311 return 0; 39 return 0;
312 40
313 return -EINVAL; 41 arch = normalize_arch(thread->mg->machine->env->arch);
314}
315#endif
316
317static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
318{
319 struct addr_location al;
320
321 thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
322 MAP__FUNCTION, ip, &al);
323 if (!al.map) {
324 /*
325 * We've seen cases (softice) where DWARF unwinder went
326 * through non executable mmaps, which we need to lookup
327 * in MAP__VARIABLE tree.
328 */
329 thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
330 MAP__VARIABLE, ip, &al);
331 }
332 return al.map;
333}
334
335static int
336find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
337 int need_unwind_info, void *arg)
338{
339 struct unwind_info *ui = arg;
340 struct map *map;
341 unw_dyn_info_t di;
342 u64 table_data, segbase, fde_count;
343 int ret = -EINVAL;
344
345 map = find_map(ip, ui);
346 if (!map || !map->dso)
347 return -EINVAL;
348
349 pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
350
351 /* Check the .eh_frame section for unwinding info */
352 if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
353 &table_data, &segbase, &fde_count)) {
354 memset(&di, 0, sizeof(di));
355 di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
356 di.start_ip = map->start;
357 di.end_ip = map->end;
358 di.u.rti.segbase = map->start + segbase;
359 di.u.rti.table_data = map->start + table_data;
360 di.u.rti.table_len = fde_count * sizeof(struct table_entry)
361 / sizeof(unw_word_t);
362 ret = dwarf_search_unwind_table(as, ip, &di, pi,
363 need_unwind_info, arg);
364 }
365
366#ifndef NO_LIBUNWIND_DEBUG_FRAME
367 /* Check the .debug_frame section for unwinding info */
368 if (ret < 0 &&
369 !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
370 int fd = dso__data_get_fd(map->dso, ui->machine);
371 int is_exec = elf_is_exec(fd, map->dso->name);
372 unw_word_t base = is_exec ? 0 : map->start;
373 const char *symfile;
374
375 if (fd >= 0)
376 dso__data_put_fd(map->dso);
377
378 symfile = map->dso->symsrc_filename ?: map->dso->name;
379
380 memset(&di, 0, sizeof(di));
381 if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
382 map->start, map->end))
383 return dwarf_search_unwind_table(as, ip, &di, pi,
384 need_unwind_info, arg);
385 }
386#endif
387
388 return ret;
389}
390
391static int access_fpreg(unw_addr_space_t __maybe_unused as,
392 unw_regnum_t __maybe_unused num,
393 unw_fpreg_t __maybe_unused *val,
394 int __maybe_unused __write,
395 void __maybe_unused *arg)
396{
397 pr_err("unwind: access_fpreg unsupported\n");
398 return -UNW_EINVAL;
399}
400
401static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as,
402 unw_word_t __maybe_unused *dil_addr,
403 void __maybe_unused *arg)
404{
405 return -UNW_ENOINFO;
406}
407
408static int resume(unw_addr_space_t __maybe_unused as,
409 unw_cursor_t __maybe_unused *cu,
410 void __maybe_unused *arg)
411{
412 pr_err("unwind: resume unsupported\n");
413 return -UNW_EINVAL;
414}
415 42
416static int 43 if (!strcmp(arch, "x86")) {
417get_proc_name(unw_addr_space_t __maybe_unused as, 44 if (dso_type != DSO__TYPE_64BIT)
418 unw_word_t __maybe_unused addr, 45 ops = x86_32_unwind_libunwind_ops;
419 char __maybe_unused *bufp, size_t __maybe_unused buf_len, 46 } else if (!strcmp(arch, "arm64") || !strcmp(arch, "arm")) {
420 unw_word_t __maybe_unused *offp, void __maybe_unused *arg) 47 if (dso_type == DSO__TYPE_64BIT)
421{ 48 ops = arm64_unwind_libunwind_ops;
422 pr_err("unwind: get_proc_name unsupported\n");
423 return -UNW_EINVAL;
424}
425
426static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
427 unw_word_t *data)
428{
429 struct map *map;
430 ssize_t size;
431
432 map = find_map(addr, ui);
433 if (!map) {
434 pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
435 return -1;
436 } 49 }
437 50
438 if (!map->dso) 51 if (!ops) {
52 pr_err("unwind: target platform=%s is not supported\n", arch);
439 return -1; 53 return -1;
440
441 size = dso__data_read_addr(map->dso, map, ui->machine,
442 addr, (u8 *) data, sizeof(*data));
443
444 return !(size == sizeof(*data));
445}
446
447static int access_mem(unw_addr_space_t __maybe_unused as,
448 unw_word_t addr, unw_word_t *valp,
449 int __write, void *arg)
450{
451 struct unwind_info *ui = arg;
452 struct stack_dump *stack = &ui->sample->user_stack;
453 u64 start, end;
454 int offset;
455 int ret;
456
457 /* Don't support write, probably not needed. */
458 if (__write || !stack || !ui->sample->user_regs.regs) {
459 *valp = 0;
460 return 0;
461 }
462
463 ret = perf_reg_value(&start, &ui->sample->user_regs, PERF_REG_SP);
464 if (ret)
465 return ret;
466
467 end = start + stack->size;
468
469 /* Check overflow. */
470 if (addr + sizeof(unw_word_t) < addr)
471 return -EINVAL;
472
473 if (addr < start || addr + sizeof(unw_word_t) >= end) {
474 ret = access_dso_mem(ui, addr, valp);
475 if (ret) {
476 pr_debug("unwind: access_mem %p not inside range"
477 " 0x%" PRIx64 "-0x%" PRIx64 "\n",
478 (void *) (uintptr_t) addr, start, end);
479 *valp = 0;
480 return ret;
481 }
482 return 0;
483 }
484
485 offset = addr - start;
486 *valp = *(unw_word_t *)&stack->data[offset];
487 pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
488 (void *) (uintptr_t) addr, (unsigned long)*valp, offset);
489 return 0;
490}
491
492static int access_reg(unw_addr_space_t __maybe_unused as,
493 unw_regnum_t regnum, unw_word_t *valp,
494 int __write, void *arg)
495{
496 struct unwind_info *ui = arg;
497 int id, ret;
498 u64 val;
499
500 /* Don't support write, I suspect we don't need it. */
501 if (__write) {
502 pr_err("unwind: access_reg w %d\n", regnum);
503 return 0;
504 }
505
506 if (!ui->sample->user_regs.regs) {
507 *valp = 0;
508 return 0;
509 }
510
511 id = libunwind__arch_reg_id(regnum);
512 if (id < 0)
513 return -EINVAL;
514
515 ret = perf_reg_value(&val, &ui->sample->user_regs, id);
516 if (ret) {
517 pr_err("unwind: can't read reg %d\n", regnum);
518 return ret;
519 }
520
521 *valp = (unw_word_t) val;
522 pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp);
523 return 0;
524}
525
526static void put_unwind_info(unw_addr_space_t __maybe_unused as,
527 unw_proc_info_t *pi __maybe_unused,
528 void *arg __maybe_unused)
529{
530 pr_debug("unwind: put_unwind_info called\n");
531}
532
533static int entry(u64 ip, struct thread *thread,
534 unwind_entry_cb_t cb, void *arg)
535{
536 struct unwind_entry e;
537 struct addr_location al;
538
539 thread__find_addr_location(thread, PERF_RECORD_MISC_USER,
540 MAP__FUNCTION, ip, &al);
541
542 e.ip = ip;
543 e.map = al.map;
544 e.sym = al.sym;
545
546 pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
547 al.sym ? al.sym->name : "''",
548 ip,
549 al.map ? al.map->map_ip(al.map, ip) : (u64) 0);
550
551 return cb(&e, arg);
552}
553
554static void display_error(int err)
555{
556 switch (err) {
557 case UNW_EINVAL:
558 pr_err("unwind: Only supports local.\n");
559 break;
560 case UNW_EUNSPEC:
561 pr_err("unwind: Unspecified error.\n");
562 break;
563 case UNW_EBADREG:
564 pr_err("unwind: Register unavailable.\n");
565 break;
566 default:
567 break;
568 }
569}
570
571static unw_accessors_t accessors = {
572 .find_proc_info = find_proc_info,
573 .put_unwind_info = put_unwind_info,
574 .get_dyn_info_list_addr = get_dyn_info_list_addr,
575 .access_mem = access_mem,
576 .access_reg = access_reg,
577 .access_fpreg = access_fpreg,
578 .resume = resume,
579 .get_proc_name = get_proc_name,
580};
581
582int unwind__prepare_access(struct thread *thread)
583{
584 if (callchain_param.record_mode != CALLCHAIN_DWARF)
585 return 0;
586
587 thread->addr_space = unw_create_addr_space(&accessors, 0);
588 if (!thread->addr_space) {
589 pr_err("unwind: Can't create unwind address space.\n");
590 return -ENOMEM;
591 } 54 }
55out_register:
56 unwind__register_ops(thread, ops);
592 57
593 unw_set_caching_policy(thread->addr_space, UNW_CACHE_GLOBAL); 58 err = thread->unwind_libunwind_ops->prepare_access(thread);
594 return 0; 59 if (initialized)
60 *initialized = err ? false : true;
61 return err;
595} 62}
596 63
597void unwind__flush_access(struct thread *thread) 64void unwind__flush_access(struct thread *thread)
598{ 65{
599 if (callchain_param.record_mode != CALLCHAIN_DWARF) 66 if (thread->unwind_libunwind_ops)
600 return; 67 thread->unwind_libunwind_ops->flush_access(thread);
601
602 unw_flush_cache(thread->addr_space, 0, 0);
603} 68}
604 69
605void unwind__finish_access(struct thread *thread) 70void unwind__finish_access(struct thread *thread)
606{ 71{
607 if (callchain_param.record_mode != CALLCHAIN_DWARF) 72 if (thread->unwind_libunwind_ops)
608 return; 73 thread->unwind_libunwind_ops->finish_access(thread);
609
610 unw_destroy_addr_space(thread->addr_space);
611}
612
613static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
614 void *arg, int max_stack)
615{
616 u64 val;
617 unw_word_t ips[max_stack];
618 unw_addr_space_t addr_space;
619 unw_cursor_t c;
620 int ret, i = 0;
621
622 ret = perf_reg_value(&val, &ui->sample->user_regs, PERF_REG_IP);
623 if (ret)
624 return ret;
625
626 ips[i++] = (unw_word_t) val;
627
628 /*
629 * If we need more than one entry, do the DWARF
630 * unwind itself.
631 */
632 if (max_stack - 1 > 0) {
633 WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
634 addr_space = ui->thread->addr_space;
635
636 if (addr_space == NULL)
637 return -1;
638
639 ret = unw_init_remote(&c, addr_space, ui);
640 if (ret)
641 display_error(ret);
642
643 while (!ret && (unw_step(&c) > 0) && i < max_stack) {
644 unw_get_reg(&c, UNW_REG_IP, &ips[i]);
645 ++i;
646 }
647
648 max_stack = i;
649 }
650
651 /*
652 * Display what we got based on the order setup.
653 */
654 for (i = 0; i < max_stack && !ret; i++) {
655 int j = i;
656
657 if (callchain_param.order == ORDER_CALLER)
658 j = max_stack - i - 1;
659 ret = ips[j] ? entry(ips[j], ui->thread, cb, arg) : 0;
660 }
661
662 return ret;
663} 74}
664 75
665int unwind__get_entries(unwind_entry_cb_t cb, void *arg, 76int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
666 struct thread *thread, 77 struct thread *thread,
667 struct perf_sample *data, int max_stack) 78 struct perf_sample *data, int max_stack)
668{ 79{
669 struct unwind_info ui = { 80 if (thread->unwind_libunwind_ops)
670 .sample = data, 81 return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack);
671 .thread = thread, 82 return 0;
672 .machine = thread->mg->machine,
673 };
674
675 if (!data->user_regs.regs)
676 return -EINVAL;
677
678 if (max_stack <= 0)
679 return -EINVAL;
680
681 return get_entries(&ui, cb, arg, max_stack);
682} 83}
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index 12790cf94618..61fb1e90ff51 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -14,18 +14,42 @@ struct unwind_entry {
14 14
15typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg); 15typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
16 16
17struct unwind_libunwind_ops {
18 int (*prepare_access)(struct thread *thread);
19 void (*flush_access)(struct thread *thread);
20 void (*finish_access)(struct thread *thread);
21 int (*get_entries)(unwind_entry_cb_t cb, void *arg,
22 struct thread *thread,
23 struct perf_sample *data, int max_stack);
24};
25
17#ifdef HAVE_DWARF_UNWIND_SUPPORT 26#ifdef HAVE_DWARF_UNWIND_SUPPORT
18int unwind__get_entries(unwind_entry_cb_t cb, void *arg, 27int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
19 struct thread *thread, 28 struct thread *thread,
20 struct perf_sample *data, int max_stack); 29 struct perf_sample *data, int max_stack);
21/* libunwind specific */ 30/* libunwind specific */
22#ifdef HAVE_LIBUNWIND_SUPPORT 31#ifdef HAVE_LIBUNWIND_SUPPORT
23int libunwind__arch_reg_id(int regnum); 32#ifndef LIBUNWIND__ARCH_REG_ID
24int unwind__prepare_access(struct thread *thread); 33#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__arch_reg_id(regnum)
34#endif
35
36#ifndef LIBUNWIND__ARCH_REG_SP
37#define LIBUNWIND__ARCH_REG_SP PERF_REG_SP
38#endif
39
40#ifndef LIBUNWIND__ARCH_REG_IP
41#define LIBUNWIND__ARCH_REG_IP PERF_REG_IP
42#endif
43
44int LIBUNWIND__ARCH_REG_ID(int regnum);
45int unwind__prepare_access(struct thread *thread, struct map *map,
46 bool *initialized);
25void unwind__flush_access(struct thread *thread); 47void unwind__flush_access(struct thread *thread);
26void unwind__finish_access(struct thread *thread); 48void unwind__finish_access(struct thread *thread);
27#else 49#else
28static inline int unwind__prepare_access(struct thread *thread __maybe_unused) 50static inline int unwind__prepare_access(struct thread *thread __maybe_unused,
51 struct map *map __maybe_unused,
52 bool *initialized __maybe_unused)
29{ 53{
30 return 0; 54 return 0;
31} 55}
@@ -44,7 +68,9 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
44 return 0; 68 return 0;
45} 69}
46 70
47static inline int unwind__prepare_access(struct thread *thread __maybe_unused) 71static inline int unwind__prepare_access(struct thread *thread __maybe_unused,
72 struct map *map __maybe_unused,
73 bool *initialized __maybe_unused)
48{ 74{
49 return 0; 75 return 0;
50} 76}
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 23504ad5d6dd..cee559d8c9e8 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -19,12 +19,19 @@
19#include "callchain.h" 19#include "callchain.h"
20#include "strlist.h" 20#include "strlist.h"
21 21
22struct callchain_param callchain_param = { 22#define CALLCHAIN_PARAM_DEFAULT \
23 .mode = CHAIN_GRAPH_ABS, 23 .mode = CHAIN_GRAPH_ABS, \
24 .min_percent = 0.5, 24 .min_percent = 0.5, \
25 .order = ORDER_CALLEE, 25 .order = ORDER_CALLEE, \
26 .key = CCKEY_FUNCTION, 26 .key = CCKEY_FUNCTION, \
27 .value = CCVAL_PERCENT, 27 .value = CCVAL_PERCENT, \
28
29struct callchain_param callchain_param = {
30 CALLCHAIN_PARAM_DEFAULT
31};
32
33struct callchain_param callchain_param_default = {
34 CALLCHAIN_PARAM_DEFAULT
28}; 35};
29 36
30/* 37/*
@@ -97,20 +104,17 @@ int rm_rf(char *path)
97 scnprintf(namebuf, sizeof(namebuf), "%s/%s", 104 scnprintf(namebuf, sizeof(namebuf), "%s/%s",
98 path, d->d_name); 105 path, d->d_name);
99 106
100 ret = stat(namebuf, &statbuf); 107 /* We have to check symbolic link itself */
108 ret = lstat(namebuf, &statbuf);
101 if (ret < 0) { 109 if (ret < 0) {
102 pr_debug("stat failed: %s\n", namebuf); 110 pr_debug("stat failed: %s\n", namebuf);
103 break; 111 break;
104 } 112 }
105 113
106 if (S_ISREG(statbuf.st_mode)) 114 if (S_ISDIR(statbuf.st_mode))
107 ret = unlink(namebuf);
108 else if (S_ISDIR(statbuf.st_mode))
109 ret = rm_rf(namebuf); 115 ret = rm_rf(namebuf);
110 else { 116 else
111 pr_debug("unknown file: %s\n", namebuf); 117 ret = unlink(namebuf);
112 ret = -1;
113 }
114 } 118 }
115 closedir(dir); 119 closedir(dir);
116 120
@@ -742,3 +746,19 @@ void print_binary(unsigned char *data, size_t len,
742 } 746 }
743 printer(BINARY_PRINT_DATA_END, -1, extra); 747 printer(BINARY_PRINT_DATA_END, -1, extra);
744} 748}
749
750int is_printable_array(char *p, unsigned int len)
751{
752 unsigned int i;
753
754 if (!p || !len || p[len - 1] != 0)
755 return 0;
756
757 len--;
758
759 for (i = 0; i < len; i++) {
760 if (!isprint(p[i]) && !isspace(p[i]))
761 return 0;
762 }
763 return 1;
764}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 1e8c3167b9fb..e5f55477491d 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -72,7 +72,6 @@
72#include <sys/ioctl.h> 72#include <sys/ioctl.h>
73#include <inttypes.h> 73#include <inttypes.h>
74#include <linux/kernel.h> 74#include <linux/kernel.h>
75#include <linux/magic.h>
76#include <linux/types.h> 75#include <linux/types.h>
77#include <sys/ttydefaults.h> 76#include <sys/ttydefaults.h>
78#include <api/fs/tracing_path.h> 77#include <api/fs/tracing_path.h>
@@ -360,4 +359,10 @@ typedef void (*print_binary_t)(enum binary_printer_ops,
360void print_binary(unsigned char *data, size_t len, 359void print_binary(unsigned char *data, size_t len,
361 size_t bytes_per_line, print_binary_t printer, 360 size_t bytes_per_line, print_binary_t printer,
362 void *extra); 361 void *extra);
362
363#if !defined(__GLIBC__) && !defined(__ANDROID__)
364extern int sched_getcpu(void);
365#endif
366
367int is_printable_array(char *p, unsigned int len);
363#endif /* GIT_COMPAT_UTIL_H */ 368#endif /* GIT_COMPAT_UTIL_H */
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index 44d440da15dc..7bdcad484225 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -134,8 +134,6 @@ static struct dso *__machine__addnew_vdso(struct machine *machine, const char *s
134 return dso; 134 return dso;
135} 135}
136 136
137#if BITS_PER_LONG == 64
138
139static enum dso_type machine__thread_dso_type(struct machine *machine, 137static enum dso_type machine__thread_dso_type(struct machine *machine,
140 struct thread *thread) 138 struct thread *thread)
141{ 139{
@@ -156,6 +154,8 @@ static enum dso_type machine__thread_dso_type(struct machine *machine,
156 return dso_type; 154 return dso_type;
157} 155}
158 156
157#if BITS_PER_LONG == 64
158
159static int vdso__do_copy_compat(FILE *f, int fd) 159static int vdso__do_copy_compat(FILE *f, int fd)
160{ 160{
161 char buf[4096]; 161 char buf[4096];
@@ -283,8 +283,38 @@ static int __machine__findnew_vdso_compat(struct machine *machine,
283 283
284#endif 284#endif
285 285
286static struct dso *machine__find_vdso(struct machine *machine,
287 struct thread *thread)
288{
289 struct dso *dso = NULL;
290 enum dso_type dso_type;
291
292 dso_type = machine__thread_dso_type(machine, thread);
293 switch (dso_type) {
294 case DSO__TYPE_32BIT:
295 dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO32, true);
296 if (!dso) {
297 dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO,
298 true);
299 if (dso && dso_type != dso__type(dso, machine))
300 dso = NULL;
301 }
302 break;
303 case DSO__TYPE_X32BIT:
304 dso = __dsos__find(&machine->dsos, DSO__NAME_VDSOX32, true);
305 break;
306 case DSO__TYPE_64BIT:
307 case DSO__TYPE_UNKNOWN:
308 default:
309 dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, true);
310 break;
311 }
312
313 return dso;
314}
315
286struct dso *machine__findnew_vdso(struct machine *machine, 316struct dso *machine__findnew_vdso(struct machine *machine,
287 struct thread *thread __maybe_unused) 317 struct thread *thread)
288{ 318{
289 struct vdso_info *vdso_info; 319 struct vdso_info *vdso_info;
290 struct dso *dso = NULL; 320 struct dso *dso = NULL;
@@ -297,6 +327,10 @@ struct dso *machine__findnew_vdso(struct machine *machine,
297 if (!vdso_info) 327 if (!vdso_info)
298 goto out_unlock; 328 goto out_unlock;
299 329
330 dso = machine__find_vdso(machine, thread);
331 if (dso)
332 goto out_unlock;
333
300#if BITS_PER_LONG == 64 334#if BITS_PER_LONG == 64
301 if (__machine__findnew_vdso_compat(machine, thread, vdso_info, &dso)) 335 if (__machine__findnew_vdso_compat(machine, thread, vdso_info, &dso))
302 goto out_unlock; 336 goto out_unlock;
diff --git a/tools/power/acpi/Makefile.config b/tools/power/acpi/Makefile.config
index 552af68d5414..a538ff44b108 100644
--- a/tools/power/acpi/Makefile.config
+++ b/tools/power/acpi/Makefile.config
@@ -54,9 +54,10 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM}
54# to something more interesting, like "arm-linux-". If you want 54# to something more interesting, like "arm-linux-". If you want
55# to compile vs uClibc, that can be done here as well. 55# to compile vs uClibc, that can be done here as well.
56CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- 56CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
57CC = $(CROSS)gcc 57CROSS_COMPILE ?= $(CROSS)
58LD = $(CROSS)gcc 58CC = $(CROSS_COMPILE)gcc
59STRIP = $(CROSS)strip 59LD = $(CROSS_COMPILE)gcc
60STRIP = $(CROSS_COMPILE)strip
60HOSTCC = gcc 61HOSTCC = gcc
61 62
62# check if compiler option is supported 63# check if compiler option is supported
diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile
index e367b1a85d70..8561e7ddca59 100644
--- a/tools/power/x86/turbostat/Makefile
+++ b/tools/power/x86/turbostat/Makefile
@@ -1,7 +1,7 @@
1CC = $(CROSS_COMPILE)gcc 1CC = $(CROSS_COMPILE)gcc
2BUILD_OUTPUT := $(CURDIR) 2BUILD_OUTPUT := $(CURDIR)
3PREFIX := /usr 3PREFIX ?= /usr
4DESTDIR := 4DESTDIR ?=
5 5
6ifeq ("$(origin O)", "command line") 6ifeq ("$(origin O)", "command line")
7 BUILD_OUTPUT := $(O) 7 BUILD_OUTPUT := $(O)
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 89a55d5e32f3..492e84fbebfa 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -123,7 +123,7 @@ cpu0: MSR_NHM_PLATFORM_INFO: 0x80838f3012300
12335 * 100 = 3500 MHz TSC frequency 12335 * 100 = 3500 MHz TSC frequency
124cpu0: MSR_IA32_POWER_CTL: 0x0004005d (C1E auto-promotion: DISabled) 124cpu0: MSR_IA32_POWER_CTL: 0x0004005d (C1E auto-promotion: DISabled)
125cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e000400 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, UNlocked: pkg-cstate-limit=0: pc0) 125cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e000400 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, UNlocked: pkg-cstate-limit=0: pc0)
126cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727 126cpu0: MSR_TURBO_RATIO_LIMIT: 0x25262727
12737 * 100 = 3700 MHz max turbo 4 active cores 12737 * 100 = 3700 MHz max turbo 4 active cores
12838 * 100 = 3800 MHz max turbo 3 active cores 12838 * 100 = 3800 MHz max turbo 3 active cores
12939 * 100 = 3900 MHz max turbo 2 active cores 12939 * 100 = 3900 MHz max turbo 2 active cores
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index acbf7ff2ee6e..3e199b508a96 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -1480,7 +1480,7 @@ dump_knl_turbo_ratio_limits(void)
1480 unsigned int cores[buckets_no]; 1480 unsigned int cores[buckets_no];
1481 unsigned int ratio[buckets_no]; 1481 unsigned int ratio[buckets_no];
1482 1482
1483 get_msr(base_cpu, MSR_NHM_TURBO_RATIO_LIMIT, &msr); 1483 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
1484 1484
1485 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", 1485 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n",
1486 base_cpu, msr); 1486 base_cpu, msr);
diff --git a/tools/scripts/Makefile.arch b/tools/scripts/Makefile.arch
index e11fbd6fae78..ad85b921a607 100644
--- a/tools/scripts/Makefile.arch
+++ b/tools/scripts/Makefile.arch
@@ -1,8 +1,4 @@
1ifndef ARCH 1HOSTARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
2ARCH := $(shell uname -m 2>/dev/null || echo not)
3endif
4
5ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
6 -e s/sun4u/sparc/ -e s/sparc64/sparc/ \ 2 -e s/sun4u/sparc/ -e s/sparc64/sparc/ \
7 -e /arm64/!s/arm.*/arm/ -e s/sa110/arm/ \ 3 -e /arm64/!s/arm.*/arm/ -e s/sa110/arm/ \
8 -e s/s390x/s390/ -e s/parisc64/parisc/ \ 4 -e s/s390x/s390/ -e s/parisc64/parisc/ \
@@ -10,6 +6,41 @@ ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
10 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ 6 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
11 -e s/tile.*/tile/ ) 7 -e s/tile.*/tile/ )
12 8
9ifndef ARCH
10ARCH := $(HOSTARCH)
11endif
12
13SRCARCH := $(ARCH)
14
15# Additional ARCH settings for x86
16ifeq ($(ARCH),i386)
17 SRCARCH := x86
18endif
19ifeq ($(ARCH),x86_64)
20 SRCARCH := x86
21endif
22
23# Additional ARCH settings for sparc
24ifeq ($(ARCH),sparc32)
25 SRCARCH := sparc
26endif
27ifeq ($(ARCH),sparc64)
28 SRCARCH := sparc
29endif
30
31# Additional ARCH settings for sh
32ifeq ($(ARCH),sh64)
33 SRCARCH := sh
34endif
35
36# Additional ARCH settings for tile
37ifeq ($(ARCH),tilepro)
38 SRCARCH := tile
39endif
40ifeq ($(ARCH),tilegx)
41 SRCARCH := tile
42endif
43
13LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) 44LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1)
14ifeq ($(LP64), 1) 45ifeq ($(LP64), 1)
15 IS_64_BIT := 1 46 IS_64_BIT := 1
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index 785985677159..ad6dd0543019 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -11,12 +11,14 @@ ldflags-y += --wrap=__devm_release_region
11ldflags-y += --wrap=__request_region 11ldflags-y += --wrap=__request_region
12ldflags-y += --wrap=__release_region 12ldflags-y += --wrap=__release_region
13ldflags-y += --wrap=devm_memremap_pages 13ldflags-y += --wrap=devm_memremap_pages
14ldflags-y += --wrap=phys_to_pfn_t 14ldflags-y += --wrap=insert_resource
15ldflags-y += --wrap=remove_resource
15 16
16DRIVERS := ../../../drivers 17DRIVERS := ../../../drivers
17NVDIMM_SRC := $(DRIVERS)/nvdimm 18NVDIMM_SRC := $(DRIVERS)/nvdimm
18ACPI_SRC := $(DRIVERS)/acpi 19ACPI_SRC := $(DRIVERS)/acpi/nfit
19DAX_SRC := $(DRIVERS)/dax 20DAX_SRC := $(DRIVERS)/dax
21ccflags-y := -I$(src)/$(NVDIMM_SRC)/
20 22
21obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o 23obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o
22obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o 24obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o
@@ -27,10 +29,12 @@ obj-$(CONFIG_ACPI_NFIT) += nfit.o
27obj-$(CONFIG_DEV_DAX) += dax.o 29obj-$(CONFIG_DEV_DAX) += dax.o
28obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o 30obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
29 31
30nfit-y := $(ACPI_SRC)/nfit.o 32nfit-y := $(ACPI_SRC)/core.o
33nfit-$(CONFIG_X86_MCE) += $(ACPI_SRC)/mce.o
31nfit-y += config_check.o 34nfit-y += config_check.o
32 35
33nd_pmem-y := $(NVDIMM_SRC)/pmem.o 36nd_pmem-y := $(NVDIMM_SRC)/pmem.o
37nd_pmem-y += pmem-dax.o
34nd_pmem-y += config_check.o 38nd_pmem-y += config_check.o
35 39
36nd_btt-y := $(NVDIMM_SRC)/btt.o 40nd_btt-y := $(NVDIMM_SRC)/btt.o
diff --git a/tools/testing/nvdimm/config_check.c b/tools/testing/nvdimm/config_check.c
index adf18bfeca00..878daf3429e8 100644
--- a/tools/testing/nvdimm/config_check.c
+++ b/tools/testing/nvdimm/config_check.c
@@ -10,6 +10,7 @@ void check(void)
10 BUILD_BUG_ON(!IS_MODULE(CONFIG_LIBNVDIMM)); 10 BUILD_BUG_ON(!IS_MODULE(CONFIG_LIBNVDIMM));
11 BUILD_BUG_ON(!IS_MODULE(CONFIG_BLK_DEV_PMEM)); 11 BUILD_BUG_ON(!IS_MODULE(CONFIG_BLK_DEV_PMEM));
12 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BTT)); 12 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BTT));
13 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_PFN));
13 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BLK)); 14 BUILD_BUG_ON(!IS_MODULE(CONFIG_ND_BLK));
14 BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT)); 15 BUILD_BUG_ON(!IS_MODULE(CONFIG_ACPI_NFIT));
15 BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX)); 16 BUILD_BUG_ON(!IS_MODULE(CONFIG_DEV_DAX));
diff --git a/tools/testing/nvdimm/pmem-dax.c b/tools/testing/nvdimm/pmem-dax.c
new file mode 100644
index 000000000000..c9b8c48f85fc
--- /dev/null
+++ b/tools/testing/nvdimm/pmem-dax.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) 2014-2016, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13#include "test/nfit_test.h"
14#include <linux/blkdev.h>
15#include <pmem.h>
16#include <nd.h>
17
18long pmem_direct_access(struct block_device *bdev, sector_t sector,
19 void **kaddr, pfn_t *pfn, long size)
20{
21 struct pmem_device *pmem = bdev->bd_queue->queuedata;
22 resource_size_t offset = sector * 512 + pmem->data_offset;
23
24 if (unlikely(is_bad_pmem(&pmem->bb, sector, size)))
25 return -EIO;
26
27 /*
28 * Limit dax to a single page at a time given vmalloc()-backed
29 * in the nfit_test case.
30 */
31 if (get_nfit_res(pmem->phys_addr + offset)) {
32 struct page *page;
33
34 *kaddr = pmem->virt_addr + offset;
35 page = vmalloc_to_page(pmem->virt_addr + offset);
36 *pfn = page_to_pfn_t(page);
37 dev_dbg_ratelimited(disk_to_dev(bdev->bd_disk)->parent,
38 "%s: sector: %#llx pfn: %#lx\n", __func__,
39 (unsigned long long) sector, page_to_pfn(page));
40
41 return PAGE_SIZE;
42 }
43
44 *kaddr = pmem->virt_addr + offset;
45 *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
46
47 /*
48 * If badblocks are present, limit known good range to the
49 * requested range.
50 */
51 if (unlikely(pmem->bb.count))
52 return size;
53 return pmem->size - pmem->pfn_pad - offset;
54}
diff --git a/tools/testing/nvdimm/test/Kbuild b/tools/testing/nvdimm/test/Kbuild
index 9241064970fe..d32f25bba42a 100644
--- a/tools/testing/nvdimm/test/Kbuild
+++ b/tools/testing/nvdimm/test/Kbuild
@@ -1,5 +1,5 @@
1ccflags-y := -I$(src)/../../../../drivers/nvdimm/ 1ccflags-y := -I$(src)/../../../../drivers/nvdimm/
2ccflags-y += -I$(src)/../../../../drivers/acpi/ 2ccflags-y += -I$(src)/../../../../drivers/acpi/nfit/
3 3
4obj-m += nfit_test.o 4obj-m += nfit_test.o
5obj-m += nfit_test_iomap.o 5obj-m += nfit_test_iomap.o
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index c842095f2801..c29f8dca9e67 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -10,11 +10,13 @@
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details. 11 * General Public License for more details.
12 */ 12 */
13#include <linux/memremap.h>
13#include <linux/rculist.h> 14#include <linux/rculist.h>
14#include <linux/export.h> 15#include <linux/export.h>
15#include <linux/ioport.h> 16#include <linux/ioport.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/pfn_t.h>
18#include <linux/io.h> 20#include <linux/io.h>
19#include <linux/mm.h> 21#include <linux/mm.h>
20#include "nfit_test.h" 22#include "nfit_test.h"
@@ -52,7 +54,7 @@ static struct nfit_test_resource *__get_nfit_res(resource_size_t resource)
52 return NULL; 54 return NULL;
53} 55}
54 56
55static struct nfit_test_resource *get_nfit_res(resource_size_t resource) 57struct nfit_test_resource *get_nfit_res(resource_size_t resource)
56{ 58{
57 struct nfit_test_resource *res; 59 struct nfit_test_resource *res;
58 60
@@ -62,6 +64,7 @@ static struct nfit_test_resource *get_nfit_res(resource_size_t resource)
62 64
63 return res; 65 return res;
64} 66}
67EXPORT_SYMBOL(get_nfit_res);
65 68
66void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size, 69void __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size,
67 void __iomem *(*fallback_fn)(resource_size_t, unsigned long)) 70 void __iomem *(*fallback_fn)(resource_size_t, unsigned long))
@@ -97,10 +100,6 @@ void *__wrap_devm_memremap(struct device *dev, resource_size_t offset,
97} 100}
98EXPORT_SYMBOL(__wrap_devm_memremap); 101EXPORT_SYMBOL(__wrap_devm_memremap);
99 102
100#ifdef __HAVE_ARCH_PTE_DEVMAP
101#include <linux/memremap.h>
102#include <linux/pfn_t.h>
103
104void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res, 103void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res,
105 struct percpu_ref *ref, struct vmem_altmap *altmap) 104 struct percpu_ref *ref, struct vmem_altmap *altmap)
106{ 105{
@@ -122,19 +121,6 @@ pfn_t __wrap_phys_to_pfn_t(phys_addr_t addr, unsigned long flags)
122 return phys_to_pfn_t(addr, flags); 121 return phys_to_pfn_t(addr, flags);
123} 122}
124EXPORT_SYMBOL(__wrap_phys_to_pfn_t); 123EXPORT_SYMBOL(__wrap_phys_to_pfn_t);
125#else
126/* to be removed post 4.5-rc1 */
127void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res)
128{
129 resource_size_t offset = res->start;
130 struct nfit_test_resource *nfit_res = get_nfit_res(offset);
131
132 if (nfit_res)
133 return nfit_res->buf + offset - nfit_res->res->start;
134 return devm_memremap_pages(dev, res);
135}
136EXPORT_SYMBOL(__wrap_devm_memremap_pages);
137#endif
138 124
139void *__wrap_memremap(resource_size_t offset, size_t size, 125void *__wrap_memremap(resource_size_t offset, size_t size,
140 unsigned long flags) 126 unsigned long flags)
@@ -229,6 +215,22 @@ struct resource *__wrap___request_region(struct resource *parent,
229} 215}
230EXPORT_SYMBOL(__wrap___request_region); 216EXPORT_SYMBOL(__wrap___request_region);
231 217
218int __wrap_insert_resource(struct resource *parent, struct resource *res)
219{
220 if (get_nfit_res(res->start))
221 return 0;
222 return insert_resource(parent, res);
223}
224EXPORT_SYMBOL(__wrap_insert_resource);
225
226int __wrap_remove_resource(struct resource *res)
227{
228 if (get_nfit_res(res->start))
229 return 0;
230 return remove_resource(res);
231}
232EXPORT_SYMBOL(__wrap_remove_resource);
233
232struct resource *__wrap___devm_request_region(struct device *dev, 234struct resource *__wrap___devm_request_region(struct device *dev,
233 struct resource *parent, resource_size_t start, 235 struct resource *parent, resource_size_t start,
234 resource_size_t n, const char *name) 236 resource_size_t n, const char *name)
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index c919866853a0..5404efa578a3 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -98,11 +98,13 @@
98enum { 98enum {
99 NUM_PM = 3, 99 NUM_PM = 3,
100 NUM_DCR = 5, 100 NUM_DCR = 5,
101 NUM_HINTS = 8,
101 NUM_BDW = NUM_DCR, 102 NUM_BDW = NUM_DCR,
102 NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW, 103 NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW,
103 NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */, 104 NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */,
104 DIMM_SIZE = SZ_32M, 105 DIMM_SIZE = SZ_32M,
105 LABEL_SIZE = SZ_128K, 106 LABEL_SIZE = SZ_128K,
107 SPA_VCD_SIZE = SZ_4M,
106 SPA0_SIZE = DIMM_SIZE, 108 SPA0_SIZE = DIMM_SIZE,
107 SPA1_SIZE = DIMM_SIZE*2, 109 SPA1_SIZE = DIMM_SIZE*2,
108 SPA2_SIZE = DIMM_SIZE, 110 SPA2_SIZE = DIMM_SIZE,
@@ -470,11 +472,7 @@ static void release_nfit_res(void *data)
470 list_del(&nfit_res->list); 472 list_del(&nfit_res->list);
471 spin_unlock(&nfit_test_lock); 473 spin_unlock(&nfit_test_lock);
472 474
473 if (is_vmalloc_addr(nfit_res->buf)) 475 vfree(nfit_res->buf);
474 vfree(nfit_res->buf);
475 else
476 dma_free_coherent(nfit_res->dev, resource_size(res),
477 nfit_res->buf, res->start);
478 kfree(res); 476 kfree(res);
479 kfree(nfit_res); 477 kfree(nfit_res);
480} 478}
@@ -507,9 +505,7 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
507 505
508 return nfit_res->buf; 506 return nfit_res->buf;
509 err: 507 err:
510 if (buf && !is_vmalloc_addr(buf)) 508 if (buf)
511 dma_free_coherent(dev, size, buf, *dma);
512 else if (buf)
513 vfree(buf); 509 vfree(buf);
514 kfree(res); 510 kfree(res);
515 kfree(nfit_res); 511 kfree(nfit_res);
@@ -524,15 +520,6 @@ static void *test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma)
524 return __test_alloc(t, size, dma, buf); 520 return __test_alloc(t, size, dma, buf);
525} 521}
526 522
527static void *test_alloc_coherent(struct nfit_test *t, size_t size,
528 dma_addr_t *dma)
529{
530 struct device *dev = &t->pdev.dev;
531 void *buf = dma_alloc_coherent(dev, size, dma, GFP_KERNEL);
532
533 return __test_alloc(t, size, dma, buf);
534}
535
536static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr) 523static struct nfit_test_resource *nfit_test_lookup(resource_size_t addr)
537{ 524{
538 int i; 525 int i;
@@ -584,7 +571,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
584 + offsetof(struct acpi_nfit_control_region, 571 + offsetof(struct acpi_nfit_control_region,
585 window_size) * NUM_DCR 572 window_size) * NUM_DCR
586 + sizeof(struct acpi_nfit_data_region) * NUM_BDW 573 + sizeof(struct acpi_nfit_data_region) * NUM_BDW
587 + sizeof(struct acpi_nfit_flush_address) * NUM_DCR; 574 + (sizeof(struct acpi_nfit_flush_address)
575 + sizeof(u64) * NUM_HINTS) * NUM_DCR;
588 int i; 576 int i;
589 577
590 t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma); 578 t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
@@ -592,15 +580,15 @@ static int nfit_test0_alloc(struct nfit_test *t)
592 return -ENOMEM; 580 return -ENOMEM;
593 t->nfit_size = nfit_size; 581 t->nfit_size = nfit_size;
594 582
595 t->spa_set[0] = test_alloc_coherent(t, SPA0_SIZE, &t->spa_set_dma[0]); 583 t->spa_set[0] = test_alloc(t, SPA0_SIZE, &t->spa_set_dma[0]);
596 if (!t->spa_set[0]) 584 if (!t->spa_set[0])
597 return -ENOMEM; 585 return -ENOMEM;
598 586
599 t->spa_set[1] = test_alloc_coherent(t, SPA1_SIZE, &t->spa_set_dma[1]); 587 t->spa_set[1] = test_alloc(t, SPA1_SIZE, &t->spa_set_dma[1]);
600 if (!t->spa_set[1]) 588 if (!t->spa_set[1])
601 return -ENOMEM; 589 return -ENOMEM;
602 590
603 t->spa_set[2] = test_alloc_coherent(t, SPA0_SIZE, &t->spa_set_dma[2]); 591 t->spa_set[2] = test_alloc(t, SPA0_SIZE, &t->spa_set_dma[2]);
604 if (!t->spa_set[2]) 592 if (!t->spa_set[2])
605 return -ENOMEM; 593 return -ENOMEM;
606 594
@@ -614,7 +602,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
614 return -ENOMEM; 602 return -ENOMEM;
615 sprintf(t->label[i], "label%d", i); 603 sprintf(t->label[i], "label%d", i);
616 604
617 t->flush[i] = test_alloc(t, 8, &t->flush_dma[i]); 605 t->flush[i] = test_alloc(t, sizeof(u64) * NUM_HINTS,
606 &t->flush_dma[i]);
618 if (!t->flush[i]) 607 if (!t->flush[i])
619 return -ENOMEM; 608 return -ENOMEM;
620 } 609 }
@@ -630,7 +619,7 @@ static int nfit_test0_alloc(struct nfit_test *t)
630 619
631static int nfit_test1_alloc(struct nfit_test *t) 620static int nfit_test1_alloc(struct nfit_test *t)
632{ 621{
633 size_t nfit_size = sizeof(struct acpi_nfit_system_address) 622 size_t nfit_size = sizeof(struct acpi_nfit_system_address) * 2
634 + sizeof(struct acpi_nfit_memory_map) 623 + sizeof(struct acpi_nfit_memory_map)
635 + offsetof(struct acpi_nfit_control_region, window_size); 624 + offsetof(struct acpi_nfit_control_region, window_size);
636 625
@@ -639,15 +628,31 @@ static int nfit_test1_alloc(struct nfit_test *t)
639 return -ENOMEM; 628 return -ENOMEM;
640 t->nfit_size = nfit_size; 629 t->nfit_size = nfit_size;
641 630
642 t->spa_set[0] = test_alloc_coherent(t, SPA2_SIZE, &t->spa_set_dma[0]); 631 t->spa_set[0] = test_alloc(t, SPA2_SIZE, &t->spa_set_dma[0]);
643 if (!t->spa_set[0]) 632 if (!t->spa_set[0])
644 return -ENOMEM; 633 return -ENOMEM;
645 634
635 t->spa_set[1] = test_alloc(t, SPA_VCD_SIZE, &t->spa_set_dma[1]);
636 if (!t->spa_set[1])
637 return -ENOMEM;
638
646 return ars_state_init(&t->pdev.dev, &t->ars_state); 639 return ars_state_init(&t->pdev.dev, &t->ars_state);
647} 640}
648 641
642static void dcr_common_init(struct acpi_nfit_control_region *dcr)
643{
644 dcr->vendor_id = 0xabcd;
645 dcr->device_id = 0;
646 dcr->revision_id = 1;
647 dcr->valid_fields = 1;
648 dcr->manufacturing_location = 0xa;
649 dcr->manufacturing_date = cpu_to_be16(2016);
650}
651
649static void nfit_test0_setup(struct nfit_test *t) 652static void nfit_test0_setup(struct nfit_test *t)
650{ 653{
654 const int flush_hint_size = sizeof(struct acpi_nfit_flush_address)
655 + (sizeof(u64) * NUM_HINTS);
651 struct acpi_nfit_desc *acpi_desc; 656 struct acpi_nfit_desc *acpi_desc;
652 struct acpi_nfit_memory_map *memdev; 657 struct acpi_nfit_memory_map *memdev;
653 void *nfit_buf = t->nfit_buf; 658 void *nfit_buf = t->nfit_buf;
@@ -655,7 +660,7 @@ static void nfit_test0_setup(struct nfit_test *t)
655 struct acpi_nfit_control_region *dcr; 660 struct acpi_nfit_control_region *dcr;
656 struct acpi_nfit_data_region *bdw; 661 struct acpi_nfit_data_region *bdw;
657 struct acpi_nfit_flush_address *flush; 662 struct acpi_nfit_flush_address *flush;
658 unsigned int offset; 663 unsigned int offset, i;
659 664
660 /* 665 /*
661 * spa0 (interleave first half of dimm0 and dimm1, note storage 666 * spa0 (interleave first half of dimm0 and dimm1, note storage
@@ -972,9 +977,7 @@ static void nfit_test0_setup(struct nfit_test *t)
972 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 977 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
973 dcr->header.length = sizeof(struct acpi_nfit_control_region); 978 dcr->header.length = sizeof(struct acpi_nfit_control_region);
974 dcr->region_index = 0+1; 979 dcr->region_index = 0+1;
975 dcr->vendor_id = 0xabcd; 980 dcr_common_init(dcr);
976 dcr->device_id = 0;
977 dcr->revision_id = 1;
978 dcr->serial_number = ~handle[0]; 981 dcr->serial_number = ~handle[0];
979 dcr->code = NFIT_FIC_BLK; 982 dcr->code = NFIT_FIC_BLK;
980 dcr->windows = 1; 983 dcr->windows = 1;
@@ -989,9 +992,7 @@ static void nfit_test0_setup(struct nfit_test *t)
989 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 992 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
990 dcr->header.length = sizeof(struct acpi_nfit_control_region); 993 dcr->header.length = sizeof(struct acpi_nfit_control_region);
991 dcr->region_index = 1+1; 994 dcr->region_index = 1+1;
992 dcr->vendor_id = 0xabcd; 995 dcr_common_init(dcr);
993 dcr->device_id = 0;
994 dcr->revision_id = 1;
995 dcr->serial_number = ~handle[1]; 996 dcr->serial_number = ~handle[1];
996 dcr->code = NFIT_FIC_BLK; 997 dcr->code = NFIT_FIC_BLK;
997 dcr->windows = 1; 998 dcr->windows = 1;
@@ -1006,9 +1007,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1006 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1007 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1007 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1008 dcr->header.length = sizeof(struct acpi_nfit_control_region);
1008 dcr->region_index = 2+1; 1009 dcr->region_index = 2+1;
1009 dcr->vendor_id = 0xabcd; 1010 dcr_common_init(dcr);
1010 dcr->device_id = 0;
1011 dcr->revision_id = 1;
1012 dcr->serial_number = ~handle[2]; 1011 dcr->serial_number = ~handle[2];
1013 dcr->code = NFIT_FIC_BLK; 1012 dcr->code = NFIT_FIC_BLK;
1014 dcr->windows = 1; 1013 dcr->windows = 1;
@@ -1023,9 +1022,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1023 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1022 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1024 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1023 dcr->header.length = sizeof(struct acpi_nfit_control_region);
1025 dcr->region_index = 3+1; 1024 dcr->region_index = 3+1;
1026 dcr->vendor_id = 0xabcd; 1025 dcr_common_init(dcr);
1027 dcr->device_id = 0;
1028 dcr->revision_id = 1;
1029 dcr->serial_number = ~handle[3]; 1026 dcr->serial_number = ~handle[3];
1030 dcr->code = NFIT_FIC_BLK; 1027 dcr->code = NFIT_FIC_BLK;
1031 dcr->windows = 1; 1028 dcr->windows = 1;
@@ -1042,9 +1039,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1042 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1039 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1043 window_size); 1040 window_size);
1044 dcr->region_index = 4+1; 1041 dcr->region_index = 4+1;
1045 dcr->vendor_id = 0xabcd; 1042 dcr_common_init(dcr);
1046 dcr->device_id = 0;
1047 dcr->revision_id = 1;
1048 dcr->serial_number = ~handle[0]; 1043 dcr->serial_number = ~handle[0];
1049 dcr->code = NFIT_FIC_BYTEN; 1044 dcr->code = NFIT_FIC_BYTEN;
1050 dcr->windows = 0; 1045 dcr->windows = 0;
@@ -1056,9 +1051,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1056 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1051 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1057 window_size); 1052 window_size);
1058 dcr->region_index = 5+1; 1053 dcr->region_index = 5+1;
1059 dcr->vendor_id = 0xabcd; 1054 dcr_common_init(dcr);
1060 dcr->device_id = 0;
1061 dcr->revision_id = 1;
1062 dcr->serial_number = ~handle[1]; 1055 dcr->serial_number = ~handle[1];
1063 dcr->code = NFIT_FIC_BYTEN; 1056 dcr->code = NFIT_FIC_BYTEN;
1064 dcr->windows = 0; 1057 dcr->windows = 0;
@@ -1070,9 +1063,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1070 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1063 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1071 window_size); 1064 window_size);
1072 dcr->region_index = 6+1; 1065 dcr->region_index = 6+1;
1073 dcr->vendor_id = 0xabcd; 1066 dcr_common_init(dcr);
1074 dcr->device_id = 0;
1075 dcr->revision_id = 1;
1076 dcr->serial_number = ~handle[2]; 1067 dcr->serial_number = ~handle[2];
1077 dcr->code = NFIT_FIC_BYTEN; 1068 dcr->code = NFIT_FIC_BYTEN;
1078 dcr->windows = 0; 1069 dcr->windows = 0;
@@ -1084,9 +1075,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1084 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1075 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1085 window_size); 1076 window_size);
1086 dcr->region_index = 7+1; 1077 dcr->region_index = 7+1;
1087 dcr->vendor_id = 0xabcd; 1078 dcr_common_init(dcr);
1088 dcr->device_id = 0;
1089 dcr->revision_id = 1;
1090 dcr->serial_number = ~handle[3]; 1079 dcr->serial_number = ~handle[3];
1091 dcr->code = NFIT_FIC_BYTEN; 1080 dcr->code = NFIT_FIC_BYTEN;
1092 dcr->windows = 0; 1081 dcr->windows = 0;
@@ -1141,45 +1130,47 @@ static void nfit_test0_setup(struct nfit_test *t)
1141 /* flush0 (dimm0) */ 1130 /* flush0 (dimm0) */
1142 flush = nfit_buf + offset; 1131 flush = nfit_buf + offset;
1143 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1132 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1144 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1133 flush->header.length = flush_hint_size;
1145 flush->device_handle = handle[0]; 1134 flush->device_handle = handle[0];
1146 flush->hint_count = 1; 1135 flush->hint_count = NUM_HINTS;
1147 flush->hint_address[0] = t->flush_dma[0]; 1136 for (i = 0; i < NUM_HINTS; i++)
1137 flush->hint_address[i] = t->flush_dma[0] + i * sizeof(u64);
1148 1138
1149 /* flush1 (dimm1) */ 1139 /* flush1 (dimm1) */
1150 flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 1; 1140 flush = nfit_buf + offset + flush_hint_size * 1;
1151 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1141 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1152 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1142 flush->header.length = flush_hint_size;
1153 flush->device_handle = handle[1]; 1143 flush->device_handle = handle[1];
1154 flush->hint_count = 1; 1144 flush->hint_count = NUM_HINTS;
1155 flush->hint_address[0] = t->flush_dma[1]; 1145 for (i = 0; i < NUM_HINTS; i++)
1146 flush->hint_address[i] = t->flush_dma[1] + i * sizeof(u64);
1156 1147
1157 /* flush2 (dimm2) */ 1148 /* flush2 (dimm2) */
1158 flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 2; 1149 flush = nfit_buf + offset + flush_hint_size * 2;
1159 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1150 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1160 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1151 flush->header.length = flush_hint_size;
1161 flush->device_handle = handle[2]; 1152 flush->device_handle = handle[2];
1162 flush->hint_count = 1; 1153 flush->hint_count = NUM_HINTS;
1163 flush->hint_address[0] = t->flush_dma[2]; 1154 for (i = 0; i < NUM_HINTS; i++)
1155 flush->hint_address[i] = t->flush_dma[2] + i * sizeof(u64);
1164 1156
1165 /* flush3 (dimm3) */ 1157 /* flush3 (dimm3) */
1166 flush = nfit_buf + offset + sizeof(struct acpi_nfit_flush_address) * 3; 1158 flush = nfit_buf + offset + flush_hint_size * 3;
1167 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1159 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1168 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1160 flush->header.length = flush_hint_size;
1169 flush->device_handle = handle[3]; 1161 flush->device_handle = handle[3];
1170 flush->hint_count = 1; 1162 flush->hint_count = NUM_HINTS;
1171 flush->hint_address[0] = t->flush_dma[3]; 1163 for (i = 0; i < NUM_HINTS; i++)
1164 flush->hint_address[i] = t->flush_dma[3] + i * sizeof(u64);
1172 1165
1173 if (t->setup_hotplug) { 1166 if (t->setup_hotplug) {
1174 offset = offset + sizeof(struct acpi_nfit_flush_address) * 4; 1167 offset = offset + flush_hint_size * 4;
1175 /* dcr-descriptor4: blk */ 1168 /* dcr-descriptor4: blk */
1176 dcr = nfit_buf + offset; 1169 dcr = nfit_buf + offset;
1177 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION; 1170 dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
1178 dcr->header.length = sizeof(struct acpi_nfit_control_region); 1171 dcr->header.length = sizeof(struct acpi_nfit_control_region);
1179 dcr->region_index = 8+1; 1172 dcr->region_index = 8+1;
1180 dcr->vendor_id = 0xabcd; 1173 dcr_common_init(dcr);
1181 dcr->device_id = 0;
1182 dcr->revision_id = 1;
1183 dcr->serial_number = ~handle[4]; 1174 dcr->serial_number = ~handle[4];
1184 dcr->code = NFIT_FIC_BLK; 1175 dcr->code = NFIT_FIC_BLK;
1185 dcr->windows = 1; 1176 dcr->windows = 1;
@@ -1196,9 +1187,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1196 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1187 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1197 window_size); 1188 window_size);
1198 dcr->region_index = 9+1; 1189 dcr->region_index = 9+1;
1199 dcr->vendor_id = 0xabcd; 1190 dcr_common_init(dcr);
1200 dcr->device_id = 0;
1201 dcr->revision_id = 1;
1202 dcr->serial_number = ~handle[4]; 1191 dcr->serial_number = ~handle[4];
1203 dcr->code = NFIT_FIC_BYTEN; 1192 dcr->code = NFIT_FIC_BYTEN;
1204 dcr->windows = 0; 1193 dcr->windows = 0;
@@ -1300,10 +1289,12 @@ static void nfit_test0_setup(struct nfit_test *t)
1300 /* flush3 (dimm4) */ 1289 /* flush3 (dimm4) */
1301 flush = nfit_buf + offset; 1290 flush = nfit_buf + offset;
1302 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS; 1291 flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
1303 flush->header.length = sizeof(struct acpi_nfit_flush_address); 1292 flush->header.length = flush_hint_size;
1304 flush->device_handle = handle[4]; 1293 flush->device_handle = handle[4];
1305 flush->hint_count = 1; 1294 flush->hint_count = NUM_HINTS;
1306 flush->hint_address[0] = t->flush_dma[4]; 1295 for (i = 0; i < NUM_HINTS; i++)
1296 flush->hint_address[i] = t->flush_dma[4]
1297 + i * sizeof(u64);
1307 } 1298 }
1308 1299
1309 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE); 1300 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE);
@@ -1339,7 +1330,16 @@ static void nfit_test1_setup(struct nfit_test *t)
1339 spa->address = t->spa_set_dma[0]; 1330 spa->address = t->spa_set_dma[0];
1340 spa->length = SPA2_SIZE; 1331 spa->length = SPA2_SIZE;
1341 1332
1342 offset += sizeof(*spa); 1333 /* virtual cd region */
1334 spa = nfit_buf + sizeof(*spa);
1335 spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
1336 spa->header.length = sizeof(*spa);
1337 memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_VCD), 16);
1338 spa->range_index = 0;
1339 spa->address = t->spa_set_dma[1];
1340 spa->length = SPA_VCD_SIZE;
1341
1342 offset += sizeof(*spa) * 2;
1343 /* mem-region0 (spa0, dimm0) */ 1343 /* mem-region0 (spa0, dimm0) */
1344 memdev = nfit_buf + offset; 1344 memdev = nfit_buf + offset;
1345 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP; 1345 memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -1365,9 +1365,7 @@ static void nfit_test1_setup(struct nfit_test *t)
1365 dcr->header.length = offsetof(struct acpi_nfit_control_region, 1365 dcr->header.length = offsetof(struct acpi_nfit_control_region,
1366 window_size); 1366 window_size);
1367 dcr->region_index = 0+1; 1367 dcr->region_index = 0+1;
1368 dcr->vendor_id = 0xabcd; 1368 dcr_common_init(dcr);
1369 dcr->device_id = 0;
1370 dcr->revision_id = 1;
1371 dcr->serial_number = ~0; 1369 dcr->serial_number = ~0;
1372 dcr->code = NFIT_FIC_BYTE; 1370 dcr->code = NFIT_FIC_BYTE;
1373 dcr->windows = 0; 1371 dcr->windows = 0;
@@ -1462,20 +1460,16 @@ static int nfit_test_probe(struct platform_device *pdev)
1462 nfit_test->setup(nfit_test); 1460 nfit_test->setup(nfit_test);
1463 acpi_desc = &nfit_test->acpi_desc; 1461 acpi_desc = &nfit_test->acpi_desc;
1464 acpi_nfit_desc_init(acpi_desc, &pdev->dev); 1462 acpi_nfit_desc_init(acpi_desc, &pdev->dev);
1465 acpi_desc->nfit = nfit_test->nfit_buf;
1466 acpi_desc->blk_do_io = nfit_test_blk_do_io; 1463 acpi_desc->blk_do_io = nfit_test_blk_do_io;
1467 nd_desc = &acpi_desc->nd_desc; 1464 nd_desc = &acpi_desc->nd_desc;
1468 nd_desc->provider_name = NULL; 1465 nd_desc->provider_name = NULL;
1466 nd_desc->module = THIS_MODULE;
1469 nd_desc->ndctl = nfit_test_ctl; 1467 nd_desc->ndctl = nfit_test_ctl;
1470 acpi_desc->nvdimm_bus = nvdimm_bus_register(&pdev->dev, nd_desc);
1471 if (!acpi_desc->nvdimm_bus)
1472 return -ENXIO;
1473 1468
1474 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_size); 1469 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1475 if (rc) { 1470 nfit_test->nfit_size);
1476 nvdimm_bus_unregister(acpi_desc->nvdimm_bus); 1471 if (rc)
1477 return rc; 1472 return rc;
1478 }
1479 1473
1480 if (nfit_test->setup != nfit_test0_setup) 1474 if (nfit_test->setup != nfit_test0_setup)
1481 return 0; 1475 return 0;
@@ -1483,22 +1477,16 @@ static int nfit_test_probe(struct platform_device *pdev)
1483 nfit_test->setup_hotplug = 1; 1477 nfit_test->setup_hotplug = 1;
1484 nfit_test->setup(nfit_test); 1478 nfit_test->setup(nfit_test);
1485 1479
1486 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_size); 1480 rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
1487 if (rc) { 1481 nfit_test->nfit_size);
1488 nvdimm_bus_unregister(acpi_desc->nvdimm_bus); 1482 if (rc)
1489 return rc; 1483 return rc;
1490 }
1491 1484
1492 return 0; 1485 return 0;
1493} 1486}
1494 1487
1495static int nfit_test_remove(struct platform_device *pdev) 1488static int nfit_test_remove(struct platform_device *pdev)
1496{ 1489{
1497 struct nfit_test *nfit_test = to_nfit_test(&pdev->dev);
1498 struct acpi_nfit_desc *acpi_desc = &nfit_test->acpi_desc;
1499
1500 nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
1501
1502 return 0; 1490 return 0;
1503} 1491}
1504 1492
@@ -1523,12 +1511,6 @@ static struct platform_driver nfit_test_driver = {
1523 .id_table = nfit_test_id, 1511 .id_table = nfit_test_id,
1524}; 1512};
1525 1513
1526#ifdef CONFIG_CMA_SIZE_MBYTES
1527#define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
1528#else
1529#define CMA_SIZE_MBYTES 0
1530#endif
1531
1532static __init int nfit_test_init(void) 1514static __init int nfit_test_init(void)
1533{ 1515{
1534 int rc, i; 1516 int rc, i;
@@ -1538,7 +1520,6 @@ static __init int nfit_test_init(void)
1538 for (i = 0; i < NUM_NFITS; i++) { 1520 for (i = 0; i < NUM_NFITS; i++) {
1539 struct nfit_test *nfit_test; 1521 struct nfit_test *nfit_test;
1540 struct platform_device *pdev; 1522 struct platform_device *pdev;
1541 static int once;
1542 1523
1543 nfit_test = kzalloc(sizeof(*nfit_test), GFP_KERNEL); 1524 nfit_test = kzalloc(sizeof(*nfit_test), GFP_KERNEL);
1544 if (!nfit_test) { 1525 if (!nfit_test) {
@@ -1577,20 +1558,6 @@ static __init int nfit_test_init(void)
1577 goto err_register; 1558 goto err_register;
1578 1559
1579 instances[i] = nfit_test; 1560 instances[i] = nfit_test;
1580
1581 if (!once++) {
1582 dma_addr_t dma;
1583 void *buf;
1584
1585 buf = dma_alloc_coherent(&pdev->dev, SZ_128M, &dma,
1586 GFP_KERNEL);
1587 if (!buf) {
1588 rc = -ENOMEM;
1589 dev_warn(&pdev->dev, "need 128M of free cma\n");
1590 goto err_register;
1591 }
1592 dma_free_coherent(&pdev->dev, SZ_128M, buf, dma);
1593 }
1594 } 1561 }
1595 1562
1596 rc = platform_driver_register(&nfit_test_driver); 1563 rc = platform_driver_register(&nfit_test_driver);
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index 96c5e16d7db9..9f18e2a4a862 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -12,6 +12,7 @@
12 */ 12 */
13#ifndef __NFIT_TEST_H__ 13#ifndef __NFIT_TEST_H__
14#define __NFIT_TEST_H__ 14#define __NFIT_TEST_H__
15#include <linux/list.h>
15 16
16struct nfit_test_resource { 17struct nfit_test_resource {
17 struct list_head list; 18 struct list_head list;
@@ -26,4 +27,5 @@ void __iomem *__wrap_ioremap_nocache(resource_size_t offset,
26void __wrap_iounmap(volatile void __iomem *addr); 27void __wrap_iounmap(volatile void __iomem *addr);
27void nfit_test_setup(nfit_test_lookup_fn lookup); 28void nfit_test_setup(nfit_test_lookup_fn lookup);
28void nfit_test_teardown(void); 29void nfit_test_teardown(void);
30struct nfit_test_resource *get_nfit_res(resource_size_t resource);
29#endif 31#endif
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 4ca83fe80654..3c40c9d0e6c7 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -12,7 +12,8 @@ CFLAGS := -Wall -O2 -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CURDIR) $
12 12
13export CFLAGS 13export CFLAGS
14 14
15SUB_DIRS = benchmarks \ 15SUB_DIRS = alignment \
16 benchmarks \
16 copyloops \ 17 copyloops \
17 context_switch \ 18 context_switch \
18 dscr \ 19 dscr \
diff --git a/tools/testing/selftests/powerpc/alignment/.gitignore b/tools/testing/selftests/powerpc/alignment/.gitignore
new file mode 100644
index 000000000000..1d980e3d7039
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/.gitignore
@@ -0,0 +1,5 @@
1copy_unaligned
2copy_first_unaligned
3paste_unaligned
4paste_last_unaligned
5copy_paste_unaligned_common
diff --git a/tools/testing/selftests/powerpc/alignment/Makefile b/tools/testing/selftests/powerpc/alignment/Makefile
new file mode 100644
index 000000000000..ad6a4e49da91
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/Makefile
@@ -0,0 +1,10 @@
1TEST_PROGS := copy_unaligned copy_first_unaligned paste_unaligned paste_last_unaligned
2
3all: $(TEST_PROGS)
4
5$(TEST_PROGS): ../harness.c ../utils.c copy_paste_unaligned_common.c
6
7include ../../lib.mk
8
9clean:
10 rm -f $(TEST_PROGS)
diff --git a/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c b/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c
new file mode 100644
index 000000000000..47b73b3a08bd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/copy_first_unaligned.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Calls to copy_first which are not 128-byte aligned should be
10 * caught and sent a SIGBUS.
11 *
12 */
13
14#include <string.h>
15#include <unistd.h>
16#include "utils.h"
17#include "instructions.h"
18#include "copy_paste_unaligned_common.h"
19
20unsigned int expected_instruction = PPC_INST_COPY_FIRST;
21unsigned int instruction_mask = 0xfc2007fe;
22
23int test_copy_first_unaligned(void)
24{
25 /* Only run this test on a P9 or later */
26 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
27
28 /* Register our signal handler with SIGBUS */
29 setup_signal_handler();
30
31 /* +1 makes buf unaligned */
32 copy_first(cacheline_buf+1);
33
34 /* We should not get here */
35 return 1;
36}
37
38int main(int argc, char *argv[])
39{
40 return test_harness(test_copy_first_unaligned, "test_copy_first_unaligned");
41}
diff --git a/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c
new file mode 100644
index 000000000000..d35fa5f5d2d3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.c
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Common code for copy, copy_first, paste and paste_last unaligned
10 * tests.
11 *
12 */
13
14#include <signal.h>
15#include <string.h>
16#include <unistd.h>
17#include "utils.h"
18#include "instructions.h"
19#include "copy_paste_unaligned_common.h"
20
21unsigned int expected_instruction;
22unsigned int instruction_mask;
23
24char cacheline_buf[128] __cacheline_aligned;
25
26void signal_action_handler(int signal_num, siginfo_t *info, void *ptr)
27{
28 ucontext_t *ctx = ptr;
29#if defined(__powerpc64__)
30 unsigned int *pc = (unsigned int *)ctx->uc_mcontext.gp_regs[PT_NIP];
31#else
32 unsigned int *pc = (unsigned int *)ctx->uc_mcontext.uc_regs->gregs[PT_NIP];
33#endif
34
35 /*
36 * Check that the signal was on the correct instruction, using a
37 * mask because the compiler assigns the register at RB.
38 */
39 if ((*pc & instruction_mask) == expected_instruction)
40 _exit(0); /* We hit the right instruction */
41
42 _exit(1);
43}
44
45void setup_signal_handler(void)
46{
47 struct sigaction signal_action;
48
49 memset(&signal_action, 0, sizeof(signal_action));
50 signal_action.sa_sigaction = signal_action_handler;
51 signal_action.sa_flags = SA_SIGINFO;
52 sigaction(SIGBUS, &signal_action, NULL);
53}
diff --git a/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h
new file mode 100644
index 000000000000..053899fe506e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/copy_paste_unaligned_common.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Declarations for common code for copy, copy_first, paste and
10 * paste_last unaligned tests.
11 *
12 */
13
14#ifndef _SELFTESTS_POWERPC_COPY_PASTE_H
15#define _SELFTESTS_POWERPC_COPY_PASTE_H
16
17#include <signal.h>
18
19int main(int argc, char *argv[]);
20void signal_action_handler(int signal_num, siginfo_t *info, void *ptr);
21void setup_signal_handler(void);
22extern char cacheline_buf[128] __cacheline_aligned;
23extern unsigned int expected_instruction;
24extern unsigned int instruction_mask;
25
26#endif /* _SELFTESTS_POWERPC_COPY_PASTE_H */
diff --git a/tools/testing/selftests/powerpc/alignment/copy_unaligned.c b/tools/testing/selftests/powerpc/alignment/copy_unaligned.c
new file mode 100644
index 000000000000..3a4e26461554
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/copy_unaligned.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Calls to copy which are not 128-byte aligned should be caught
10 * and sent a SIGBUS.
11 *
12 */
13
14#include <string.h>
15#include <unistd.h>
16#include "utils.h"
17#include "instructions.h"
18#include "copy_paste_unaligned_common.h"
19
20unsigned int expected_instruction = PPC_INST_COPY;
21unsigned int instruction_mask = 0xfc0007fe;
22
23int test_copy_unaligned(void)
24{
25 /* Only run this test on a P9 or later */
26 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
27
28 /* Register our signal handler with SIGBUS */
29 setup_signal_handler();
30
31 /* +1 makes buf unaligned */
32 copy(cacheline_buf+1);
33
34 /* We should not get here */
35 return 1;
36}
37
38int main(int argc, char *argv[])
39{
40 return test_harness(test_copy_unaligned, "test_copy_unaligned");
41}
diff --git a/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c b/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c
new file mode 100644
index 000000000000..6e0ad045fcc3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/paste_last_unaligned.c
@@ -0,0 +1,43 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Calls to paste_last which are not 128-byte aligned should be
10 * caught and sent a SIGBUS.
11 *
12 */
13
14#include <string.h>
15#include <unistd.h>
16#include "utils.h"
17#include "instructions.h"
18#include "copy_paste_unaligned_common.h"
19
20unsigned int expected_instruction = PPC_INST_PASTE_LAST;
21unsigned int instruction_mask = 0xfc2007ff;
22
23int test_paste_last_unaligned(void)
24{
25 /* Only run this test on a P9 or later */
26 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
27
28 /* Register our signal handler with SIGBUS */
29 setup_signal_handler();
30
31 copy(cacheline_buf);
32
33 /* +1 makes buf unaligned */
34 paste_last(cacheline_buf+1);
35
36 /* We should not get here */
37 return 1;
38}
39
40int main(int argc, char *argv[])
41{
42 return test_harness(test_paste_last_unaligned, "test_paste_last_unaligned");
43}
diff --git a/tools/testing/selftests/powerpc/alignment/paste_unaligned.c b/tools/testing/selftests/powerpc/alignment/paste_unaligned.c
new file mode 100644
index 000000000000..6f982b45e4bd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/alignment/paste_unaligned.c
@@ -0,0 +1,43 @@
1/*
2 * Copyright 2016, Chris Smart, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Calls to paste which are not 128-byte aligned should be caught
10 * and sent a SIGBUS.
11 *
12 */
13
14#include <string.h>
15#include <unistd.h>
16#include "utils.h"
17#include "instructions.h"
18#include "copy_paste_unaligned_common.h"
19
20unsigned int expected_instruction = PPC_INST_PASTE;
21unsigned int instruction_mask = 0xfc0007fe;
22
23int test_paste_unaligned(void)
24{
25 /* Only run this test on a P9 or later */
26 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
27
28 /* Register our signal handler with SIGBUS */
29 setup_signal_handler();
30
31 copy(cacheline_buf);
32
33 /* +1 makes buf unaligned */
34 paste(cacheline_buf+1);
35
36 /* We should not get here */
37 return 1;
38}
39
40int main(int argc, char *argv[])
41{
42 return test_harness(test_paste_unaligned, "test_paste_unaligned");
43}
diff --git a/tools/testing/selftests/powerpc/benchmarks/.gitignore b/tools/testing/selftests/powerpc/benchmarks/.gitignore
index 6fa673316ac2..bce49ebd869e 100644
--- a/tools/testing/selftests/powerpc/benchmarks/.gitignore
+++ b/tools/testing/selftests/powerpc/benchmarks/.gitignore
@@ -1,2 +1,4 @@
1gettimeofday 1gettimeofday
2context_switch 2context_switch
3mmap_bench
4futex_bench \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile
index 912445ff7ce7..a9adfb7de78f 100644
--- a/tools/testing/selftests/powerpc/benchmarks/Makefile
+++ b/tools/testing/selftests/powerpc/benchmarks/Makefile
@@ -1,4 +1,4 @@
1TEST_PROGS := gettimeofday context_switch 1TEST_PROGS := gettimeofday context_switch mmap_bench futex_bench
2 2
3CFLAGS += -O2 3CFLAGS += -O2
4 4
@@ -7,6 +7,7 @@ all: $(TEST_PROGS)
7$(TEST_PROGS): ../harness.c 7$(TEST_PROGS): ../harness.c
8 8
9context_switch: ../utils.c 9context_switch: ../utils.c
10context_switch: CFLAGS += -maltivec -mvsx -mabi=altivec
10context_switch: LDLIBS += -lpthread 11context_switch: LDLIBS += -lpthread
11 12
12include ../../lib.mk 13include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/benchmarks/context_switch.c b/tools/testing/selftests/powerpc/benchmarks/context_switch.c
index 7b785941adec..a36883ad48a4 100644
--- a/tools/testing/selftests/powerpc/benchmarks/context_switch.c
+++ b/tools/testing/selftests/powerpc/benchmarks/context_switch.c
@@ -25,7 +25,9 @@
25#include <sys/types.h> 25#include <sys/types.h>
26#include <sys/shm.h> 26#include <sys/shm.h>
27#include <linux/futex.h> 27#include <linux/futex.h>
28 28#ifdef __powerpc__
29#include <altivec.h>
30#endif
29#include "../utils.h" 31#include "../utils.h"
30 32
31static unsigned int timeout = 30; 33static unsigned int timeout = 30;
@@ -37,12 +39,15 @@ static int touch_fp = 1;
37double fp; 39double fp;
38 40
39static int touch_vector = 1; 41static int touch_vector = 1;
40typedef int v4si __attribute__ ((vector_size (16))); 42vector int a, b, c;
41v4si a, b, c;
42 43
43#ifdef __powerpc__ 44#ifdef __powerpc__
44static int touch_altivec = 1; 45static int touch_altivec = 1;
45 46
47/*
48 * Note: LTO (Link Time Optimisation) doesn't play well with this function
49 * attribute. Be very careful enabling LTO for this test.
50 */
46static void __attribute__((__target__("no-vsx"))) altivec_touch_fn(void) 51static void __attribute__((__target__("no-vsx"))) altivec_touch_fn(void)
47{ 52{
48 c = a + b; 53 c = a + b;
@@ -369,11 +374,11 @@ static void usage(void)
369 fprintf(stderr, "\t\t--process\tUse processes (default threads)\n"); 374 fprintf(stderr, "\t\t--process\tUse processes (default threads)\n");
370 fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run (default 30)\n"); 375 fprintf(stderr, "\t\t--timeout=X\tDuration in seconds to run (default 30)\n");
371 fprintf(stderr, "\t\t--vdso\t\ttouch VDSO\n"); 376 fprintf(stderr, "\t\t--vdso\t\ttouch VDSO\n");
372 fprintf(stderr, "\t\t--fp\t\ttouch FP\n"); 377 fprintf(stderr, "\t\t--no-fp\t\tDon't touch FP\n");
373#ifdef __powerpc__ 378#ifdef __powerpc__
374 fprintf(stderr, "\t\t--altivec\ttouch altivec\n"); 379 fprintf(stderr, "\t\t--no-altivec\tDon't touch altivec\n");
375#endif 380#endif
376 fprintf(stderr, "\t\t--vector\ttouch vector\n"); 381 fprintf(stderr, "\t\t--no-vector\tDon't touch vector\n");
377} 382}
378 383
379int main(int argc, char *argv[]) 384int main(int argc, char *argv[])
diff --git a/tools/testing/selftests/powerpc/benchmarks/futex_bench.c b/tools/testing/selftests/powerpc/benchmarks/futex_bench.c
new file mode 100644
index 000000000000..2fc711d9150d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/benchmarks/futex_bench.c
@@ -0,0 +1,42 @@
1/*
2 * Copyright 2016, Anton Blanchard, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#define _GNU_SOURCE
7
8#include <stdio.h>
9#include <sys/syscall.h>
10#include <time.h>
11#include <unistd.h>
12#include <linux/futex.h>
13
14#include "utils.h"
15
16#define ITERATIONS 100000000
17
18#define futex(A, B, C, D, E, F) syscall(__NR_futex, A, B, C, D, E, F)
19
20int test_futex(void)
21{
22 struct timespec ts_start, ts_end;
23 unsigned long i = ITERATIONS;
24
25 clock_gettime(CLOCK_MONOTONIC, &ts_start);
26
27 while (i--) {
28 unsigned int addr = 0;
29 futex(&addr, FUTEX_WAKE, 1, NULL, NULL, 0);
30 }
31
32 clock_gettime(CLOCK_MONOTONIC, &ts_end);
33
34 printf("time = %.6f\n", ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9);
35
36 return 0;
37}
38
39int main(void)
40{
41 return test_harness(test_futex, "futex_bench");
42}
diff --git a/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c b/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c
new file mode 100644
index 000000000000..8d084a2d6e74
--- /dev/null
+++ b/tools/testing/selftests/powerpc/benchmarks/mmap_bench.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2016, Anton Blanchard, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <sys/mman.h>
9#include <time.h>
10
11#include "utils.h"
12
13#define ITERATIONS 5000000
14
15#define MEMSIZE (128 * 1024 * 1024)
16
17int test_mmap(void)
18{
19 struct timespec ts_start, ts_end;
20 unsigned long i = ITERATIONS;
21
22 clock_gettime(CLOCK_MONOTONIC, &ts_start);
23
24 while (i--) {
25 char *c = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE,
26 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
27 FAIL_IF(c == MAP_FAILED);
28 munmap(c, MEMSIZE);
29 }
30
31 clock_gettime(CLOCK_MONOTONIC, &ts_end);
32
33 printf("time = %.6f\n", ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9);
34
35 return 0;
36}
37
38int main(void)
39{
40 return test_harness(test_mmap, "mmap_bench");
41}
diff --git a/tools/testing/selftests/powerpc/instructions.h b/tools/testing/selftests/powerpc/instructions.h
new file mode 100644
index 000000000000..0fb0bd3b28c9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/instructions.h
@@ -0,0 +1,68 @@
1#ifndef _SELFTESTS_POWERPC_INSTRUCTIONS_H
2#define _SELFTESTS_POWERPC_INSTRUCTIONS_H
3
4#include <stdio.h>
5#include <stdlib.h>
6
7/* This defines the "copy" instruction from Power ISA 3.0 Book II, section 4.4. */
8#define __COPY(RA, RB, L) \
9 (0x7c00060c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10))
10#define COPY(RA, RB, L) \
11 .long __COPY((RA), (RB), (L))
12
13static inline void copy(void *i)
14{
15 asm volatile(str(COPY(0, %0, 0))";"
16 :
17 : "b" (i)
18 : "memory"
19 );
20}
21
22static inline void copy_first(void *i)
23{
24 asm volatile(str(COPY(0, %0, 1))";"
25 :
26 : "b" (i)
27 : "memory"
28 );
29}
30
31/* This defines the "paste" instruction from Power ISA 3.0 Book II, section 4.4. */
32#define __PASTE(RA, RB, L, RC) \
33 (0x7c00070c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10) | (RC) << (31-31))
34#define PASTE(RA, RB, L, RC) \
35 .long __PASTE((RA), (RB), (L), (RC))
36
37static inline int paste(void *i)
38{
39 int cr;
40
41 asm volatile(str(PASTE(0, %1, 0, 0))";"
42 "mfcr %0;"
43 : "=r" (cr)
44 : "b" (i)
45 : "memory"
46 );
47 return cr;
48}
49
50static inline int paste_last(void *i)
51{
52 int cr;
53
54 asm volatile(str(PASTE(0, %1, 1, 1))";"
55 "mfcr %0;"
56 : "=r" (cr)
57 : "b" (i)
58 : "memory"
59 );
60 return cr;
61}
62
63#define PPC_INST_COPY __COPY(0, 0, 0)
64#define PPC_INST_COPY_FIRST __COPY(0, 0, 1)
65#define PPC_INST_PASTE __PASTE(0, 0, 0, 0)
66#define PPC_INST_PASTE_LAST __PASTE(0, 0, 1, 1)
67
68#endif /* _SELFTESTS_POWERPC_INSTRUCTIONS_H */
diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore
index b43ade0ec861..e715a3f2fbf4 100644
--- a/tools/testing/selftests/powerpc/mm/.gitignore
+++ b/tools/testing/selftests/powerpc/mm/.gitignore
@@ -1,3 +1,4 @@
1hugetlb_vs_thp_test 1hugetlb_vs_thp_test
2subpage_prot 2subpage_prot
3tempfile 3tempfile
4prot_sao \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile
index ee179e22308c..3bdb96eae558 100644
--- a/tools/testing/selftests/powerpc/mm/Makefile
+++ b/tools/testing/selftests/powerpc/mm/Makefile
@@ -1,13 +1,15 @@
1noarg: 1noarg:
2 $(MAKE) -C ../ 2 $(MAKE) -C ../
3 3
4TEST_PROGS := hugetlb_vs_thp_test subpage_prot 4TEST_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao
5TEST_FILES := tempfile 5TEST_FILES := tempfile
6 6
7all: $(TEST_PROGS) $(TEST_FILES) 7all: $(TEST_PROGS) $(TEST_FILES)
8 8
9$(TEST_PROGS): ../harness.c 9$(TEST_PROGS): ../harness.c
10 10
11prot_sao: ../utils.c
12
11include ../../lib.mk 13include ../../lib.mk
12 14
13tempfile: 15tempfile:
diff --git a/tools/testing/selftests/powerpc/mm/prot_sao.c b/tools/testing/selftests/powerpc/mm/prot_sao.c
new file mode 100644
index 000000000000..611530d43fa9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/prot_sao.c
@@ -0,0 +1,42 @@
1/*
2 * Copyright 2016, Michael Ellerman, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <sys/mman.h>
10
11#include <asm/cputable.h>
12
13#include "utils.h"
14
15#define SIZE (64 * 1024)
16
17int test_prot_sao(void)
18{
19 char *p;
20
21 /* 2.06 or later should support SAO */
22 SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
23
24 /*
25 * Ensure we can ask for PROT_SAO.
26 * We can't really verify that it does the right thing, but at least we
27 * confirm the kernel will accept it.
28 */
29 p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE | PROT_SAO,
30 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
31 FAIL_IF(p == MAP_FAILED);
32
33 /* Write to the mapping, to at least cause a fault */
34 memset(p, 0xaa, SIZE);
35
36 return 0;
37}
38
39int main(void)
40{
41 return test_harness(test_prot_sao, "prot-sao");
42}
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
index 42bddbed8b64..44b7df14a936 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
+++ b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
@@ -20,3 +20,5 @@ back_to_back_ebbs_test
20lost_exception_test 20lost_exception_test
21no_handler_test 21no_handler_test
22cycles_with_mmcr2_test 22cycles_with_mmcr2_test
23ebb_lmr
24ebb_lmr_regs \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
index 8d2279c4bb4b..6b0453e60d53 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
@@ -14,7 +14,7 @@ TEST_PROGS := reg_access_test event_attributes_test cycles_test \
14 fork_cleanup_test ebb_on_child_test \ 14 fork_cleanup_test ebb_on_child_test \
15 ebb_on_willing_child_test back_to_back_ebbs_test \ 15 ebb_on_willing_child_test back_to_back_ebbs_test \
16 lost_exception_test no_handler_test \ 16 lost_exception_test no_handler_test \
17 cycles_with_mmcr2_test 17 cycles_with_mmcr2_test ebb_lmr ebb_lmr_regs
18 18
19all: $(TEST_PROGS) 19all: $(TEST_PROGS)
20 20
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c
new file mode 100644
index 000000000000..c47ebd55ba4d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.c
@@ -0,0 +1,143 @@
1/*
2 * Copyright 2016, Jack Miller, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8
9#include "ebb.h"
10#include "ebb_lmr.h"
11
12#define SIZE (32 * 1024 * 1024) /* 32M */
13#define LM_SIZE 0 /* Smallest encoding, 32M */
14
15#define SECTIONS 64 /* 1 per bit in LMSER */
16#define SECTION_SIZE (SIZE / SECTIONS)
17#define SECTION_LONGS (SECTION_SIZE / sizeof(long))
18
19static unsigned long *test_mem;
20
21static int lmr_count = 0;
22
23void ebb_lmr_handler(void)
24{
25 lmr_count++;
26}
27
28void ldmx_full_section(unsigned long *mem, int section)
29{
30 unsigned long *ptr;
31 int i;
32
33 for (i = 0; i < SECTION_LONGS; i++) {
34 ptr = &mem[(SECTION_LONGS * section) + i];
35 ldmx((unsigned long) &ptr);
36 ebb_lmr_reset();
37 }
38}
39
40unsigned long section_masks[] = {
41 0x8000000000000000,
42 0xFF00000000000000,
43 0x0000000F70000000,
44 0x8000000000000001,
45 0xF0F0F0F0F0F0F0F0,
46 0x0F0F0F0F0F0F0F0F,
47 0x0
48};
49
50int ebb_lmr_section_test(unsigned long *mem)
51{
52 unsigned long *mask = section_masks;
53 int i;
54
55 for (; *mask; mask++) {
56 mtspr(SPRN_LMSER, *mask);
57 printf("Testing mask 0x%016lx\n", mfspr(SPRN_LMSER));
58
59 for (i = 0; i < 64; i++) {
60 lmr_count = 0;
61 ldmx_full_section(mem, i);
62 if (*mask & (1UL << (63 - i)))
63 FAIL_IF(lmr_count != SECTION_LONGS);
64 else
65 FAIL_IF(lmr_count);
66 }
67 }
68
69 return 0;
70}
71
72int ebb_lmr(void)
73{
74 int i;
75
76 SKIP_IF(!lmr_is_supported());
77
78 setup_ebb_handler(ebb_lmr_handler);
79
80 ebb_global_enable();
81
82 FAIL_IF(posix_memalign((void **)&test_mem, SIZE, SIZE) != 0);
83
84 mtspr(SPRN_LMSER, 0);
85
86 FAIL_IF(mfspr(SPRN_LMSER) != 0);
87
88 mtspr(SPRN_LMRR, ((unsigned long)test_mem | LM_SIZE));
89
90 FAIL_IF(mfspr(SPRN_LMRR) != ((unsigned long)test_mem | LM_SIZE));
91
92 /* Read every single byte to ensure we get no false positives */
93 for (i = 0; i < SECTIONS; i++)
94 ldmx_full_section(test_mem, i);
95
96 FAIL_IF(lmr_count != 0);
97
98 /* Turn on the first section */
99
100 mtspr(SPRN_LMSER, (1UL << 63));
101 FAIL_IF(mfspr(SPRN_LMSER) != (1UL << 63));
102
103 /* Enable LM (BESCR) */
104
105 mtspr(SPRN_BESCR, mfspr(SPRN_BESCR) | BESCR_LME);
106 FAIL_IF(!(mfspr(SPRN_BESCR) & BESCR_LME));
107
108 ldmx((unsigned long)&test_mem);
109
110 FAIL_IF(lmr_count != 1); // exactly one exception
111 FAIL_IF(mfspr(SPRN_BESCR) & BESCR_LME); // LM now disabled
112 FAIL_IF(!(mfspr(SPRN_BESCR) & BESCR_LMEO)); // occurred bit set
113
114 printf("Simple LMR EBB OK\n");
115
116 /* This shouldn't cause an EBB since it's been disabled */
117 ldmx((unsigned long)&test_mem);
118 FAIL_IF(lmr_count != 1);
119
120 printf("LMR disable on EBB OK\n");
121
122 ebb_lmr_reset();
123
124 /* This should cause an EBB or reset is broken */
125 ldmx((unsigned long)&test_mem);
126 FAIL_IF(lmr_count != 2);
127
128 printf("LMR reset EBB OK\n");
129
130 ebb_lmr_reset();
131
132 return ebb_lmr_section_test(test_mem);
133}
134
135int main(void)
136{
137 int ret = test_harness(ebb_lmr, "ebb_lmr");
138
139 if (test_mem)
140 free(test_mem);
141
142 return ret;
143}
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h
new file mode 100644
index 000000000000..ef50abd557cd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr.h
@@ -0,0 +1,39 @@
1#ifndef _SELFTESTS_POWERPC_PMU_EBB_LMR_H
2#define _SELFTESTS_POWERPC_PMU_EBB_LMR_H
3
4#include "reg.h"
5
6#ifndef PPC_FEATURE2_ARCH_3_00
7#define PPC_FEATURE2_ARCH_3_00 0x00800000
8#endif
9
10#define lmr_is_supported() have_hwcap2(PPC_FEATURE2_ARCH_3_00)
11
12static inline void ebb_lmr_reset(void)
13{
14 unsigned long bescr = mfspr(SPRN_BESCR);
15 bescr &= ~(BESCR_LMEO);
16 bescr |= BESCR_LME;
17 mtspr(SPRN_BESCR, bescr);
18}
19
20#define LDMX(t, a, b)\
21 (0x7c00026a | \
22 (((t) & 0x1f) << 21) | \
23 (((a) & 0x1f) << 16) | \
24 (((b) & 0x1f) << 11))
25
26static inline unsigned long ldmx(unsigned long address)
27{
28 unsigned long ret;
29
30 asm volatile ("mr 9, %1\r\n"
31 ".long " __stringify(LDMX(9, 0, 9)) "\r\n"
32 "mr %0, 9\r\n":"=r"(ret)
33 :"r"(address)
34 :"r9");
35
36 return ret;
37}
38
39#endif
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c
new file mode 100644
index 000000000000..aff4241fd88a
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_lmr_regs.c
@@ -0,0 +1,37 @@
1/*
2 * Copyright 2016, Jack Miller, IBM Corp.
3 * Licensed under GPLv2.
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8#include <unistd.h>
9
10#include "ebb.h"
11#include "ebb_lmr.h"
12
13#define CHECKS 10000
14
15int ebb_lmr_regs(void)
16{
17 int i;
18
19 SKIP_IF(!lmr_is_supported());
20
21 ebb_global_enable();
22
23 for (i = 0; i < CHECKS; i++) {
24 mtspr(SPRN_LMRR, i << 25); // skip size and rsvd bits
25 mtspr(SPRN_LMSER, i);
26
27 FAIL_IF(mfspr(SPRN_LMRR) != (i << 25));
28 FAIL_IF(mfspr(SPRN_LMSER) != i);
29 }
30
31 return 0;
32}
33
34int main(void)
35{
36 return test_harness(ebb_lmr_regs, "ebb_lmr_regs");
37}
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c b/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c
index 5da355135df2..ae9a79086111 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c
+++ b/tools/testing/selftests/powerpc/pmu/ebb/instruction_count_test.c
@@ -51,7 +51,7 @@ static int do_count_loop(struct event *event, uint64_t instructions,
51 printf("Looped for %lu instructions, overhead %lu\n", instructions, overhead); 51 printf("Looped for %lu instructions, overhead %lu\n", instructions, overhead);
52 printf("Expected %lu\n", expected); 52 printf("Expected %lu\n", expected);
53 printf("Actual %llu\n", event->result.value); 53 printf("Actual %llu\n", event->result.value);
54 printf("Error %ld, %f%%\n", difference, percentage); 54 printf("Delta %ld, %f%%\n", difference, percentage);
55 printf("Took %d EBBs\n", ebb_state.stats.ebb_count); 55 printf("Took %d EBBs\n", ebb_state.stats.ebb_count);
56 } 56 }
57 57
diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c
index a361ad3334ce..8b992fa5b478 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.c
+++ b/tools/testing/selftests/powerpc/pmu/lib.c
@@ -190,7 +190,7 @@ int parse_proc_maps(void)
190 190
191bool require_paranoia_below(int level) 191bool require_paranoia_below(int level)
192{ 192{
193 unsigned long current; 193 long current;
194 char *end, buf[16]; 194 char *end, buf[16];
195 FILE *f; 195 FILE *f;
196 int rc; 196 int rc;
@@ -208,7 +208,7 @@ bool require_paranoia_below(int level)
208 goto out_close; 208 goto out_close;
209 } 209 }
210 210
211 current = strtoul(buf, &end, 10); 211 current = strtol(buf, &end, 10);
212 212
213 if (end == buf) { 213 if (end == buf) {
214 printf("Couldn't parse " PARANOID_PATH "?\n"); 214 printf("Couldn't parse " PARANOID_PATH "?\n");
@@ -216,7 +216,7 @@ bool require_paranoia_below(int level)
216 } 216 }
217 217
218 if (current >= level) 218 if (current >= level)
219 goto out; 219 goto out_close;
220 220
221 rc = 0; 221 rc = 0;
222out_close: 222out_close:
diff --git a/tools/testing/selftests/powerpc/reg.h b/tools/testing/selftests/powerpc/reg.h
index 65bfdeeebdee..fddf368ed82f 100644
--- a/tools/testing/selftests/powerpc/reg.h
+++ b/tools/testing/selftests/powerpc/reg.h
@@ -34,6 +34,11 @@
34 34
35#define BESCR_PMEO 0x1 /* PMU Event-based exception Occurred */ 35#define BESCR_PMEO 0x1 /* PMU Event-based exception Occurred */
36#define BESCR_PME (0x1ul << 32) /* PMU Event-based exception Enable */ 36#define BESCR_PME (0x1ul << 32) /* PMU Event-based exception Enable */
37#define BESCR_LME (0x1ul << 34) /* Load Monitor Enable */
38#define BESCR_LMEO (0x1ul << 2) /* Load Monitor Exception Occurred */
39
40#define SPRN_LMRR 813 /* Load Monitor Region Register */
41#define SPRN_LMSER 814 /* Load Monitor Section Enable Register */
37 42
38#define SPRN_PMC1 771 43#define SPRN_PMC1 771
39#define SPRN_PMC2 772 44#define SPRN_PMC2 772
diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore
index bb942db845bf..82c0a9ce6e74 100644
--- a/tools/testing/selftests/powerpc/tm/.gitignore
+++ b/tools/testing/selftests/powerpc/tm/.gitignore
@@ -6,3 +6,4 @@ tm-vmxcopy
6tm-fork 6tm-fork
7tm-tar 7tm-tar
8tm-tmspr 8tm-tmspr
9tm-exec
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index d0505dbd22d5..9d301d785d9e 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -1,11 +1,14 @@
1TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack tm-vmxcopy tm-fork tm-tar tm-tmspr 1TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \
2 tm-vmxcopy tm-fork tm-tar tm-tmspr tm-exec tm-execed
2 3
3all: $(TEST_PROGS) 4all: $(TEST_PROGS)
4 5
5$(TEST_PROGS): ../harness.c ../utils.c 6$(TEST_PROGS): ../harness.c ../utils.c
6 7
8CFLAGS += -mhtm
9
7tm-syscall: tm-syscall-asm.S 10tm-syscall: tm-syscall-asm.S
8tm-syscall: CFLAGS += -mhtm -I../../../../../usr/include 11tm-syscall: CFLAGS += -I../../../../../usr/include
9tm-tmspr: CFLAGS += -pthread 12tm-tmspr: CFLAGS += -pthread
10 13
11include ../../lib.mk 14include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/tm/tm-exec.c b/tools/testing/selftests/powerpc/tm/tm-exec.c
new file mode 100644
index 000000000000..3d27fa0ece04
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-exec.c
@@ -0,0 +1,70 @@
1/*
2 * Copyright 2016, Cyril Bur, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Syscalls can be performed provided the transactions are suspended.
10 * The exec() class of syscall is unique as a new process is loaded.
11 *
12 * It makes little sense for after an exec() call for the previously
13 * suspended transaction to still exist.
14 */
15
16#define _GNU_SOURCE
17#include <errno.h>
18#include <inttypes.h>
19#include <libgen.h>
20#include <pthread.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26#include "utils.h"
27#include "tm.h"
28
29static char *path;
30
31static int test_exec(void)
32{
33 SKIP_IF(!have_htm());
34
35 asm __volatile__(
36 "tbegin.;"
37 "blt 1f; "
38 "tsuspend.;"
39 "1: ;"
40 : : : "memory");
41
42 execl(path, "tm-exec", "--child", NULL);
43
44 /* Shouldn't get here */
45 perror("execl() failed");
46 return 1;
47}
48
49static int after_exec(void)
50{
51 asm __volatile__(
52 "tbegin.;"
53 "blt 1f;"
54 "tsuspend.;"
55 "1: ;"
56 : : : "memory");
57
58 FAIL_IF(failure_is_nesting());
59 return 0;
60}
61
62int main(int argc, char *argv[])
63{
64 path = argv[0];
65
66 if (argc > 1 && strcmp(argv[1], "--child") == 0)
67 return after_exec();
68
69 return test_harness(test_exec, "tm_exec");
70}
diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall.c b/tools/testing/selftests/powerpc/tm/tm-syscall.c
index 60560cb20e38..454b965a2db3 100644
--- a/tools/testing/selftests/powerpc/tm/tm-syscall.c
+++ b/tools/testing/selftests/powerpc/tm/tm-syscall.c
@@ -27,21 +27,6 @@ unsigned retries = 0;
27#define TEST_DURATION 10 /* seconds */ 27#define TEST_DURATION 10 /* seconds */
28#define TM_RETRIES 100 28#define TM_RETRIES 100
29 29
30long failure_code(void)
31{
32 return __builtin_get_texasru() >> 24;
33}
34
35bool failure_is_persistent(void)
36{
37 return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT;
38}
39
40bool failure_is_syscall(void)
41{
42 return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL;
43}
44
45pid_t getppid_tm(bool suspend) 30pid_t getppid_tm(bool suspend)
46{ 31{
47 int i; 32 int i;
diff --git a/tools/testing/selftests/powerpc/tm/tm.h b/tools/testing/selftests/powerpc/tm/tm.h
index 24144b25772c..60318bad7d7a 100644
--- a/tools/testing/selftests/powerpc/tm/tm.h
+++ b/tools/testing/selftests/powerpc/tm/tm.h
@@ -6,8 +6,9 @@
6#ifndef _SELFTESTS_POWERPC_TM_TM_H 6#ifndef _SELFTESTS_POWERPC_TM_TM_H
7#define _SELFTESTS_POWERPC_TM_TM_H 7#define _SELFTESTS_POWERPC_TM_TM_H
8 8
9#include <stdbool.h> 9#include <asm/tm.h>
10#include <asm/cputable.h> 10#include <asm/cputable.h>
11#include <stdbool.h>
11 12
12#include "../utils.h" 13#include "../utils.h"
13 14
@@ -31,4 +32,24 @@ static inline bool have_htm_nosc(void)
31#endif 32#endif
32} 33}
33 34
35static inline long failure_code(void)
36{
37 return __builtin_get_texasru() >> 24;
38}
39
40static inline bool failure_is_persistent(void)
41{
42 return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT;
43}
44
45static inline bool failure_is_syscall(void)
46{
47 return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL;
48}
49
50static inline bool failure_is_nesting(void)
51{
52 return (__builtin_get_texasru() & 0x400000);
53}
54
34#endif /* _SELFTESTS_POWERPC_TM_TM_H */ 55#endif /* _SELFTESTS_POWERPC_TM_TM_H */
diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h
index a985cfaa535e..fbd33e52ef8f 100644
--- a/tools/testing/selftests/powerpc/utils.h
+++ b/tools/testing/selftests/powerpc/utils.h
@@ -27,6 +27,11 @@ int test_harness(int (test_function)(void), char *name);
27extern void *get_auxv_entry(int type); 27extern void *get_auxv_entry(int type);
28int pick_online_cpu(void); 28int pick_online_cpu(void);
29 29
30static inline bool have_hwcap(unsigned long ftr)
31{
32 return ((unsigned long)get_auxv_entry(AT_HWCAP) & ftr) == ftr;
33}
34
30static inline bool have_hwcap2(unsigned long ftr2) 35static inline bool have_hwcap2(unsigned long ftr2)
31{ 36{
32 return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2; 37 return ((unsigned long)get_auxv_entry(AT_HWCAP2) & ftr2) == ftr2;
diff --git a/tools/testing/selftests/rcutorture/bin/functions.sh b/tools/testing/selftests/rcutorture/bin/functions.sh
index b325470c01b3..1426a9b97494 100644
--- a/tools/testing/selftests/rcutorture/bin/functions.sh
+++ b/tools/testing/selftests/rcutorture/bin/functions.sh
@@ -99,8 +99,9 @@ configfrag_hotplug_cpu () {
99# identify_boot_image qemu-cmd 99# identify_boot_image qemu-cmd
100# 100#
101# Returns the relative path to the kernel build image. This will be 101# Returns the relative path to the kernel build image. This will be
102# arch/<arch>/boot/bzImage unless overridden with the TORTURE_BOOT_IMAGE 102# arch/<arch>/boot/bzImage or vmlinux if bzImage is not a target for the
103# environment variable. 103# architecture, unless overridden with the TORTURE_BOOT_IMAGE environment
104# variable.
104identify_boot_image () { 105identify_boot_image () {
105 if test -n "$TORTURE_BOOT_IMAGE" 106 if test -n "$TORTURE_BOOT_IMAGE"
106 then 107 then
@@ -110,11 +111,8 @@ identify_boot_image () {
110 qemu-system-x86_64|qemu-system-i386) 111 qemu-system-x86_64|qemu-system-i386)
111 echo arch/x86/boot/bzImage 112 echo arch/x86/boot/bzImage
112 ;; 113 ;;
113 qemu-system-ppc64)
114 echo arch/powerpc/boot/bzImage
115 ;;
116 *) 114 *)
117 echo "" 115 echo vmlinux
118 ;; 116 ;;
119 esac 117 esac
120 fi 118 fi
@@ -175,7 +173,7 @@ identify_qemu_args () {
175 qemu-system-x86_64|qemu-system-i386) 173 qemu-system-x86_64|qemu-system-i386)
176 ;; 174 ;;
177 qemu-system-ppc64) 175 qemu-system-ppc64)
178 echo -enable-kvm -M pseries -cpu POWER7 -nodefaults 176 echo -enable-kvm -M pseries -nodefaults
179 echo -device spapr-vscsi 177 echo -device spapr-vscsi
180 if test -n "$TORTURE_QEMU_INTERACTIVE" -a -n "$TORTURE_QEMU_MAC" 178 if test -n "$TORTURE_QEMU_INTERACTIVE" -a -n "$TORTURE_QEMU_MAC"
181 then 179 then
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
index 4109f306d855..ea6e373edc27 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
@@ -8,9 +8,9 @@
8# 8#
9# Usage: kvm-test-1-run.sh config builddir resdir seconds qemu-args boot_args 9# Usage: kvm-test-1-run.sh config builddir resdir seconds qemu-args boot_args
10# 10#
11# qemu-args defaults to "-enable-kvm -soundhw pcspk -nographic", along with 11# qemu-args defaults to "-enable-kvm -nographic", along with arguments
12# arguments specifying the number of CPUs and other 12# specifying the number of CPUs and other options
13# options generated from the underlying CPU architecture. 13# generated from the underlying CPU architecture.
14# boot_args defaults to value returned by the per_version_boot_params 14# boot_args defaults to value returned by the per_version_boot_params
15# shell function. 15# shell function.
16# 16#
@@ -96,7 +96,8 @@ if test "$base_resdir" != "$resdir" -a -f $base_resdir/bzImage -a -f $base_resdi
96then 96then
97 # Rerunning previous test, so use that test's kernel. 97 # Rerunning previous test, so use that test's kernel.
98 QEMU="`identify_qemu $base_resdir/vmlinux`" 98 QEMU="`identify_qemu $base_resdir/vmlinux`"
99 KERNEL=$base_resdir/bzImage 99 BOOT_IMAGE="`identify_boot_image $QEMU`"
100 KERNEL=$base_resdir/${BOOT_IMAGE##*/} # use the last component of ${BOOT_IMAGE}
100 ln -s $base_resdir/Make*.out $resdir # for kvm-recheck.sh 101 ln -s $base_resdir/Make*.out $resdir # for kvm-recheck.sh
101 ln -s $base_resdir/.config $resdir # for kvm-recheck.sh 102 ln -s $base_resdir/.config $resdir # for kvm-recheck.sh
102elif kvm-build.sh $config_template $builddir $T 103elif kvm-build.sh $config_template $builddir $T
@@ -110,7 +111,7 @@ then
110 if test -n "$BOOT_IMAGE" 111 if test -n "$BOOT_IMAGE"
111 then 112 then
112 cp $builddir/$BOOT_IMAGE $resdir 113 cp $builddir/$BOOT_IMAGE $resdir
113 KERNEL=$resdir/bzImage 114 KERNEL=$resdir/${BOOT_IMAGE##*/}
114 else 115 else
115 echo No identifiable boot image, not running KVM, see $resdir. 116 echo No identifiable boot image, not running KVM, see $resdir.
116 echo Do the torture scripts know about your architecture? 117 echo Do the torture scripts know about your architecture?
@@ -147,7 +148,7 @@ then
147fi 148fi
148 149
149# Generate -smp qemu argument. 150# Generate -smp qemu argument.
150qemu_args="-enable-kvm -soundhw pcspk -nographic $qemu_args" 151qemu_args="-enable-kvm -nographic $qemu_args"
151cpu_count=`configNR_CPUS.sh $config_template` 152cpu_count=`configNR_CPUS.sh $config_template`
152cpu_count=`configfrag_boot_cpus "$boot_args" "$config_template" "$cpu_count"` 153cpu_count=`configfrag_boot_cpus "$boot_args" "$config_template" "$cpu_count"`
153vcpus=`identify_qemu_vcpus` 154vcpus=`identify_qemu_vcpus`
@@ -229,6 +230,7 @@ fi
229if test $commandcompleted -eq 0 -a -n "$qemu_pid" 230if test $commandcompleted -eq 0 -a -n "$qemu_pid"
230then 231then
231 echo Grace period for qemu job at pid $qemu_pid 232 echo Grace period for qemu job at pid $qemu_pid
233 oldline="`tail $resdir/console.log`"
232 while : 234 while :
233 do 235 do
234 kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null` 236 kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null`
@@ -238,13 +240,29 @@ then
238 else 240 else
239 break 241 break
240 fi 242 fi
241 if test $kruntime -ge $((seconds + $TORTURE_SHUTDOWN_GRACE)) 243 must_continue=no
244 newline="`tail $resdir/console.log`"
245 if test "$newline" != "$oldline" && echo $newline | grep -q ' [0-9]\+us : '
246 then
247 must_continue=yes
248 fi
249 last_ts="`tail $resdir/console.log | grep '^\[ *[0-9]\+\.[0-9]\+]' | tail -1 | sed -e 's/^\[ *//' -e 's/\..*$//'`"
250 if test -z "last_ts"
251 then
252 last_ts=0
253 fi
254 if test "$newline" != "$oldline" -a "$last_ts" -lt $((seconds + $TORTURE_SHUTDOWN_GRACE))
255 then
256 must_continue=yes
257 fi
258 if test $must_continue = no -a $kruntime -ge $((seconds + $TORTURE_SHUTDOWN_GRACE))
242 then 259 then
243 echo "!!! PID $qemu_pid hung at $kruntime vs. $seconds seconds" >> $resdir/Warnings 2>&1 260 echo "!!! PID $qemu_pid hung at $kruntime vs. $seconds seconds" >> $resdir/Warnings 2>&1
244 kill -KILL $qemu_pid 261 kill -KILL $qemu_pid
245 break 262 break
246 fi 263 fi
247 sleep 1 264 oldline=$newline
265 sleep 10
248 done 266 done
249elif test -z "$qemu_pid" 267elif test -z "$qemu_pid"
250then 268then
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh
index 0d598145873e..0aed965f0062 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm.sh
@@ -48,7 +48,7 @@ resdir=""
48configs="" 48configs=""
49cpus=0 49cpus=0
50ds=`date +%Y.%m.%d-%H:%M:%S` 50ds=`date +%Y.%m.%d-%H:%M:%S`
51jitter=0 51jitter="-1"
52 52
53. functions.sh 53. functions.sh
54 54
diff --git a/tools/testing/selftests/rcutorture/bin/parse-console.sh b/tools/testing/selftests/rcutorture/bin/parse-console.sh
index 5eb49b7f864c..08aa7d50ae0e 100755
--- a/tools/testing/selftests/rcutorture/bin/parse-console.sh
+++ b/tools/testing/selftests/rcutorture/bin/parse-console.sh
@@ -33,7 +33,7 @@ if grep -Pq '\x00' < $file
33then 33then
34 print_warning Console output contains nul bytes, old qemu still running? 34 print_warning Console output contains nul bytes, old qemu still running?
35fi 35fi
36egrep 'Badness|WARNING:|Warn|BUG|===========|Call Trace:|Oops:|detected stalls on CPUs/tasks:|self-detected stall on CPU|Stall ended before state dump start|\?\?\? Writer stall state' < $file | grep -v 'ODEBUG: ' | grep -v 'Warning: unable to open an initial console' > $1.diags 36egrep 'Badness|WARNING:|Warn|BUG|===========|Call Trace:|Oops:|detected stalls on CPUs/tasks:|self-detected stall on CPU|Stall ended before state dump start|\?\?\? Writer stall state|rcu_.*kthread starved for' < $file | grep -v 'ODEBUG: ' | grep -v 'Warning: unable to open an initial console' > $1.diags
37if test -s $1.diags 37if test -s $1.diags
38then 38then
39 print_warning Assertion failure in $file $title 39 print_warning Assertion failure in $file $title
@@ -69,6 +69,11 @@ then
69 then 69 then
70 summary="$summary Stalls: $n_stalls" 70 summary="$summary Stalls: $n_stalls"
71 fi 71 fi
72 n_starves=`grep -c 'rcu_.*kthread starved for' $1`
73 if test "$n_starves" -ne 0
74 then
75 summary="$summary Starves: $n_starves"
76 fi
72 print_warning Summary: $summary 77 print_warning Summary: $summary
73else 78else
74 rm $1.diags 79 rm $1.diags
diff --git a/tools/testing/selftests/rcutorture/doc/initrd.txt b/tools/testing/selftests/rcutorture/doc/initrd.txt
index 4170e714f044..833f826d6ec2 100644
--- a/tools/testing/selftests/rcutorture/doc/initrd.txt
+++ b/tools/testing/selftests/rcutorture/doc/initrd.txt
@@ -13,6 +13,22 @@ cd initrd
13cpio -id < /tmp/initrd.img.zcat 13cpio -id < /tmp/initrd.img.zcat
14------------------------------------------------------------------------ 14------------------------------------------------------------------------
15 15
16Another way to create an initramfs image is using "dracut"[1], which is
17available on many distros, however the initramfs dracut generates is a cpio
18archive with another cpio archive in it, so an extra step is needed to create
19the initrd directory hierarchy.
20
21Here are the commands to create a initrd directory for rcutorture using
22dracut:
23
24------------------------------------------------------------------------
25dracut --no-hostonly --no-hostonly-cmdline --module "base bash shutdown" /tmp/initramfs.img
26cd tools/testing/selftests/rcutorture
27mkdir initrd
28cd initrd
29/usr/lib/dracut/skipcpio /tmp/initramfs.img | zcat | cpio -id < /tmp/initramfs.img
30------------------------------------------------------------------------
31
16Interestingly enough, if you are running rcutorture, you don't really 32Interestingly enough, if you are running rcutorture, you don't really
17need userspace in many cases. Running without userspace has the 33need userspace in many cases. Running without userspace has the
18advantage of allowing you to test your kernel independently of the 34advantage of allowing you to test your kernel independently of the
@@ -89,3 +105,9 @@ while :
89do 105do
90 sleep 10 106 sleep 10
91done 107done
108------------------------------------------------------------------------
109
110References:
111[1]: https://dracut.wiki.kernel.org/index.php/Main_Page
112[2]: http://blog.elastocloud.org/2015/06/rapid-linux-kernel-devtest-with-qemu.html
113[3]: https://www.centos.org/forums/viewtopic.php?t=51621
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 2e58549b2f02..03f1fa495d74 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1021,8 +1021,8 @@ void tracer_stop(int sig)
1021typedef void tracer_func_t(struct __test_metadata *_metadata, 1021typedef void tracer_func_t(struct __test_metadata *_metadata,
1022 pid_t tracee, int status, void *args); 1022 pid_t tracee, int status, void *args);
1023 1023
1024void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee, 1024void start_tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
1025 tracer_func_t tracer_func, void *args) 1025 tracer_func_t tracer_func, void *args, bool ptrace_syscall)
1026{ 1026{
1027 int ret = -1; 1027 int ret = -1;
1028 struct sigaction action = { 1028 struct sigaction action = {
@@ -1042,12 +1042,16 @@ void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
1042 /* Wait for attach stop */ 1042 /* Wait for attach stop */
1043 wait(NULL); 1043 wait(NULL);
1044 1044
1045 ret = ptrace(PTRACE_SETOPTIONS, tracee, NULL, PTRACE_O_TRACESECCOMP); 1045 ret = ptrace(PTRACE_SETOPTIONS, tracee, NULL, ptrace_syscall ?
1046 PTRACE_O_TRACESYSGOOD :
1047 PTRACE_O_TRACESECCOMP);
1046 ASSERT_EQ(0, ret) { 1048 ASSERT_EQ(0, ret) {
1047 TH_LOG("Failed to set PTRACE_O_TRACESECCOMP"); 1049 TH_LOG("Failed to set PTRACE_O_TRACESECCOMP");
1048 kill(tracee, SIGKILL); 1050 kill(tracee, SIGKILL);
1049 } 1051 }
1050 ptrace(PTRACE_CONT, tracee, NULL, 0); 1052 ret = ptrace(ptrace_syscall ? PTRACE_SYSCALL : PTRACE_CONT,
1053 tracee, NULL, 0);
1054 ASSERT_EQ(0, ret);
1051 1055
1052 /* Unblock the tracee */ 1056 /* Unblock the tracee */
1053 ASSERT_EQ(1, write(fd, "A", 1)); 1057 ASSERT_EQ(1, write(fd, "A", 1));
@@ -1063,12 +1067,13 @@ void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
1063 /* Child is dead. Time to go. */ 1067 /* Child is dead. Time to go. */
1064 return; 1068 return;
1065 1069
1066 /* Make sure this is a seccomp event. */ 1070 /* Check if this is a seccomp event. */
1067 ASSERT_EQ(true, IS_SECCOMP_EVENT(status)); 1071 ASSERT_EQ(!ptrace_syscall, IS_SECCOMP_EVENT(status));
1068 1072
1069 tracer_func(_metadata, tracee, status, args); 1073 tracer_func(_metadata, tracee, status, args);
1070 1074
1071 ret = ptrace(PTRACE_CONT, tracee, NULL, NULL); 1075 ret = ptrace(ptrace_syscall ? PTRACE_SYSCALL : PTRACE_CONT,
1076 tracee, NULL, 0);
1072 ASSERT_EQ(0, ret); 1077 ASSERT_EQ(0, ret);
1073 } 1078 }
1074 /* Directly report the status of our test harness results. */ 1079 /* Directly report the status of our test harness results. */
@@ -1079,7 +1084,7 @@ void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
1079void cont_handler(int num) 1084void cont_handler(int num)
1080{ } 1085{ }
1081pid_t setup_trace_fixture(struct __test_metadata *_metadata, 1086pid_t setup_trace_fixture(struct __test_metadata *_metadata,
1082 tracer_func_t func, void *args) 1087 tracer_func_t func, void *args, bool ptrace_syscall)
1083{ 1088{
1084 char sync; 1089 char sync;
1085 int pipefd[2]; 1090 int pipefd[2];
@@ -1095,7 +1100,8 @@ pid_t setup_trace_fixture(struct __test_metadata *_metadata,
1095 signal(SIGALRM, cont_handler); 1100 signal(SIGALRM, cont_handler);
1096 if (tracer_pid == 0) { 1101 if (tracer_pid == 0) {
1097 close(pipefd[0]); 1102 close(pipefd[0]);
1098 tracer(_metadata, pipefd[1], tracee, func, args); 1103 start_tracer(_metadata, pipefd[1], tracee, func, args,
1104 ptrace_syscall);
1099 syscall(__NR_exit, 0); 1105 syscall(__NR_exit, 0);
1100 } 1106 }
1101 close(pipefd[1]); 1107 close(pipefd[1]);
@@ -1177,7 +1183,7 @@ FIXTURE_SETUP(TRACE_poke)
1177 1183
1178 /* Launch tracer. */ 1184 /* Launch tracer. */
1179 self->tracer = setup_trace_fixture(_metadata, tracer_poke, 1185 self->tracer = setup_trace_fixture(_metadata, tracer_poke,
1180 &self->tracer_args); 1186 &self->tracer_args, false);
1181} 1187}
1182 1188
1183FIXTURE_TEARDOWN(TRACE_poke) 1189FIXTURE_TEARDOWN(TRACE_poke)
@@ -1399,6 +1405,29 @@ void tracer_syscall(struct __test_metadata *_metadata, pid_t tracee,
1399 1405
1400} 1406}
1401 1407
1408void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
1409 int status, void *args)
1410{
1411 int ret, nr;
1412 unsigned long msg;
1413 static bool entry;
1414
1415 /* Make sure we got an empty message. */
1416 ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
1417 EXPECT_EQ(0, ret);
1418 EXPECT_EQ(0, msg);
1419
1420 /* The only way to tell PTRACE_SYSCALL entry/exit is by counting. */
1421 entry = !entry;
1422 if (!entry)
1423 return;
1424
1425 nr = get_syscall(_metadata, tracee);
1426
1427 if (nr == __NR_getpid)
1428 change_syscall(_metadata, tracee, __NR_getppid);
1429}
1430
1402FIXTURE_DATA(TRACE_syscall) { 1431FIXTURE_DATA(TRACE_syscall) {
1403 struct sock_fprog prog; 1432 struct sock_fprog prog;
1404 pid_t tracer, mytid, mypid, parent; 1433 pid_t tracer, mytid, mypid, parent;
@@ -1440,7 +1469,8 @@ FIXTURE_SETUP(TRACE_syscall)
1440 ASSERT_NE(self->parent, self->mypid); 1469 ASSERT_NE(self->parent, self->mypid);
1441 1470
1442 /* Launch tracer. */ 1471 /* Launch tracer. */
1443 self->tracer = setup_trace_fixture(_metadata, tracer_syscall, NULL); 1472 self->tracer = setup_trace_fixture(_metadata, tracer_syscall, NULL,
1473 false);
1444} 1474}
1445 1475
1446FIXTURE_TEARDOWN(TRACE_syscall) 1476FIXTURE_TEARDOWN(TRACE_syscall)
@@ -1500,6 +1530,130 @@ TEST_F(TRACE_syscall, syscall_dropped)
1500 EXPECT_NE(self->mytid, syscall(__NR_gettid)); 1530 EXPECT_NE(self->mytid, syscall(__NR_gettid));
1501} 1531}
1502 1532
1533TEST_F(TRACE_syscall, skip_after_RET_TRACE)
1534{
1535 struct sock_filter filter[] = {
1536 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1537 offsetof(struct seccomp_data, nr)),
1538 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1539 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EPERM),
1540 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1541 };
1542 struct sock_fprog prog = {
1543 .len = (unsigned short)ARRAY_SIZE(filter),
1544 .filter = filter,
1545 };
1546 long ret;
1547
1548 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1549 ASSERT_EQ(0, ret);
1550
1551 /* Install fixture filter. */
1552 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1553 ASSERT_EQ(0, ret);
1554
1555 /* Install "errno on getppid" filter. */
1556 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1557 ASSERT_EQ(0, ret);
1558
1559 /* Tracer will redirect getpid to getppid, and we should see EPERM. */
1560 EXPECT_EQ(-1, syscall(__NR_getpid));
1561 EXPECT_EQ(EPERM, errno);
1562}
1563
1564TEST_F_SIGNAL(TRACE_syscall, kill_after_RET_TRACE, SIGSYS)
1565{
1566 struct sock_filter filter[] = {
1567 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1568 offsetof(struct seccomp_data, nr)),
1569 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1570 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
1571 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1572 };
1573 struct sock_fprog prog = {
1574 .len = (unsigned short)ARRAY_SIZE(filter),
1575 .filter = filter,
1576 };
1577 long ret;
1578
1579 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1580 ASSERT_EQ(0, ret);
1581
1582 /* Install fixture filter. */
1583 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
1584 ASSERT_EQ(0, ret);
1585
1586 /* Install "death on getppid" filter. */
1587 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1588 ASSERT_EQ(0, ret);
1589
1590 /* Tracer will redirect getpid to getppid, and we should die. */
1591 EXPECT_NE(self->mypid, syscall(__NR_getpid));
1592}
1593
1594TEST_F(TRACE_syscall, skip_after_ptrace)
1595{
1596 struct sock_filter filter[] = {
1597 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1598 offsetof(struct seccomp_data, nr)),
1599 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1600 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EPERM),
1601 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1602 };
1603 struct sock_fprog prog = {
1604 .len = (unsigned short)ARRAY_SIZE(filter),
1605 .filter = filter,
1606 };
1607 long ret;
1608
1609 /* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
1610 teardown_trace_fixture(_metadata, self->tracer);
1611 self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
1612 true);
1613
1614 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1615 ASSERT_EQ(0, ret);
1616
1617 /* Install "errno on getppid" filter. */
1618 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1619 ASSERT_EQ(0, ret);
1620
1621 /* Tracer will redirect getpid to getppid, and we should see EPERM. */
1622 EXPECT_EQ(-1, syscall(__NR_getpid));
1623 EXPECT_EQ(EPERM, errno);
1624}
1625
1626TEST_F_SIGNAL(TRACE_syscall, kill_after_ptrace, SIGSYS)
1627{
1628 struct sock_filter filter[] = {
1629 BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
1630 offsetof(struct seccomp_data, nr)),
1631 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
1632 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
1633 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
1634 };
1635 struct sock_fprog prog = {
1636 .len = (unsigned short)ARRAY_SIZE(filter),
1637 .filter = filter,
1638 };
1639 long ret;
1640
1641 /* Swap SECCOMP_RET_TRACE tracer for PTRACE_SYSCALL tracer. */
1642 teardown_trace_fixture(_metadata, self->tracer);
1643 self->tracer = setup_trace_fixture(_metadata, tracer_ptrace, NULL,
1644 true);
1645
1646 ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1647 ASSERT_EQ(0, ret);
1648
1649 /* Install "death on getppid" filter. */
1650 ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
1651 ASSERT_EQ(0, ret);
1652
1653 /* Tracer will redirect getpid to getppid, and we should die. */
1654 EXPECT_NE(self->mypid, syscall(__NR_getpid));
1655}
1656
1503#ifndef __NR_seccomp 1657#ifndef __NR_seccomp
1504# if defined(__i386__) 1658# if defined(__i386__)
1505# define __NR_seccomp 354 1659# define __NR_seccomp 354
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index c73425de3cfe..4f747ee07f10 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -4,8 +4,8 @@ include ../lib.mk
4 4
5.PHONY: all all_32 all_64 warn_32bit_failure clean 5.PHONY: all all_32 all_64 warn_32bit_failure clean
6 6
7TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall \ 7TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \
8 check_initial_reg_state sigreturn ldt_gdt iopl 8 check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test
9TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ 9TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
10 test_FCMOV test_FCOMI test_FISTTP \ 10 test_FCMOV test_FCOMI test_FISTTP \
11 vdso_restorer 11 vdso_restorer
diff --git a/tools/testing/selftests/x86/mpx-debug.h b/tools/testing/selftests/x86/mpx-debug.h
new file mode 100644
index 000000000000..9230981f2e12
--- /dev/null
+++ b/tools/testing/selftests/x86/mpx-debug.h
@@ -0,0 +1,14 @@
1#ifndef _MPX_DEBUG_H
2#define _MPX_DEBUG_H
3
4#ifndef DEBUG_LEVEL
5#define DEBUG_LEVEL 0
6#endif
7#define dprintf_level(level, args...) do { if(level <= DEBUG_LEVEL) printf(args); } while(0)
8#define dprintf1(args...) dprintf_level(1, args)
9#define dprintf2(args...) dprintf_level(2, args)
10#define dprintf3(args...) dprintf_level(3, args)
11#define dprintf4(args...) dprintf_level(4, args)
12#define dprintf5(args...) dprintf_level(5, args)
13
14#endif /* _MPX_DEBUG_H */
diff --git a/tools/testing/selftests/x86/mpx-dig.c b/tools/testing/selftests/x86/mpx-dig.c
new file mode 100644
index 000000000000..ce85356d7e2e
--- /dev/null
+++ b/tools/testing/selftests/x86/mpx-dig.c
@@ -0,0 +1,498 @@
1/*
2 * Written by Dave Hansen <dave.hansen@intel.com>
3 */
4
5#include <stdlib.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include <stdio.h>
9#include <errno.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <unistd.h>
13#include <sys/mman.h>
14#include <string.h>
15#include <fcntl.h>
16#include "mpx-debug.h"
17#include "mpx-mm.h"
18#include "mpx-hw.h"
19
20unsigned long bounds_dir_global;
21
22#define mpx_dig_abort() __mpx_dig_abort(__FILE__, __func__, __LINE__)
23static void inline __mpx_dig_abort(const char *file, const char *func, int line)
24{
25 fprintf(stderr, "MPX dig abort @ %s::%d in %s()\n", file, line, func);
26 printf("MPX dig abort @ %s::%d in %s()\n", file, line, func);
27 abort();
28}
29
30/*
31 * run like this (BDIR finds the probably bounds directory):
32 *
33 * BDIR="$(cat /proc/$pid/smaps | grep -B1 2097152 \
34 * | head -1 | awk -F- '{print $1}')";
35 * ./mpx-dig $pid 0x$BDIR
36 *
37 * NOTE:
38 * assumes that the only 2097152-kb VMA is the bounds dir
39 */
40
41long nr_incore(void *ptr, unsigned long size_bytes)
42{
43 int i;
44 long ret = 0;
45 long vec_len = size_bytes / PAGE_SIZE;
46 unsigned char *vec = malloc(vec_len);
47 int incore_ret;
48
49 if (!vec)
50 mpx_dig_abort();
51
52 incore_ret = mincore(ptr, size_bytes, vec);
53 if (incore_ret) {
54 printf("mincore ret: %d\n", incore_ret);
55 perror("mincore");
56 mpx_dig_abort();
57 }
58 for (i = 0; i < vec_len; i++)
59 ret += vec[i];
60 free(vec);
61 return ret;
62}
63
64int open_proc(int pid, char *file)
65{
66 static char buf[100];
67 int fd;
68
69 snprintf(&buf[0], sizeof(buf), "/proc/%d/%s", pid, file);
70 fd = open(&buf[0], O_RDONLY);
71 if (fd < 0)
72 perror(buf);
73
74 return fd;
75}
76
77struct vaddr_range {
78 unsigned long start;
79 unsigned long end;
80};
81struct vaddr_range *ranges;
82int nr_ranges_allocated;
83int nr_ranges_populated;
84int last_range = -1;
85
86int __pid_load_vaddrs(int pid)
87{
88 int ret = 0;
89 int proc_maps_fd = open_proc(pid, "maps");
90 char linebuf[10000];
91 unsigned long start;
92 unsigned long end;
93 char rest[1000];
94 FILE *f = fdopen(proc_maps_fd, "r");
95
96 if (!f)
97 mpx_dig_abort();
98 nr_ranges_populated = 0;
99 while (!feof(f)) {
100 char *readret = fgets(linebuf, sizeof(linebuf), f);
101 int parsed;
102
103 if (readret == NULL) {
104 if (feof(f))
105 break;
106 mpx_dig_abort();
107 }
108
109 parsed = sscanf(linebuf, "%lx-%lx%s", &start, &end, rest);
110 if (parsed != 3)
111 mpx_dig_abort();
112
113 dprintf4("result[%d]: %lx-%lx<->%s\n", parsed, start, end, rest);
114 if (nr_ranges_populated >= nr_ranges_allocated) {
115 ret = -E2BIG;
116 break;
117 }
118 ranges[nr_ranges_populated].start = start;
119 ranges[nr_ranges_populated].end = end;
120 nr_ranges_populated++;
121 }
122 last_range = -1;
123 fclose(f);
124 close(proc_maps_fd);
125 return ret;
126}
127
128int pid_load_vaddrs(int pid)
129{
130 int ret;
131
132 dprintf2("%s(%d)\n", __func__, pid);
133 if (!ranges) {
134 nr_ranges_allocated = 4;
135 ranges = malloc(nr_ranges_allocated * sizeof(ranges[0]));
136 dprintf2("%s(%d) allocated %d ranges @ %p\n", __func__, pid,
137 nr_ranges_allocated, ranges);
138 assert(ranges != NULL);
139 }
140 do {
141 ret = __pid_load_vaddrs(pid);
142 if (!ret)
143 break;
144 if (ret == -E2BIG) {
145 dprintf2("%s(%d) need to realloc\n", __func__, pid);
146 nr_ranges_allocated *= 2;
147 ranges = realloc(ranges,
148 nr_ranges_allocated * sizeof(ranges[0]));
149 dprintf2("%s(%d) allocated %d ranges @ %p\n", __func__,
150 pid, nr_ranges_allocated, ranges);
151 assert(ranges != NULL);
152 dprintf1("reallocating to hold %d ranges\n", nr_ranges_allocated);
153 }
154 } while (1);
155
156 dprintf2("%s(%d) done\n", __func__, pid);
157
158 return ret;
159}
160
161static inline int vaddr_in_range(unsigned long vaddr, struct vaddr_range *r)
162{
163 if (vaddr < r->start)
164 return 0;
165 if (vaddr >= r->end)
166 return 0;
167 return 1;
168}
169
170static inline int vaddr_mapped_by_range(unsigned long vaddr)
171{
172 int i;
173
174 if (last_range > 0 && vaddr_in_range(vaddr, &ranges[last_range]))
175 return 1;
176
177 for (i = 0; i < nr_ranges_populated; i++) {
178 struct vaddr_range *r = &ranges[i];
179
180 if (vaddr_in_range(vaddr, r))
181 continue;
182 last_range = i;
183 return 1;
184 }
185 return 0;
186}
187
188const int bt_entry_size_bytes = sizeof(unsigned long) * 4;
189
190void *read_bounds_table_into_buf(unsigned long table_vaddr)
191{
192#ifdef MPX_DIG_STANDALONE
193 static char bt_buf[MPX_BOUNDS_TABLE_SIZE_BYTES];
194 off_t seek_ret = lseek(fd, table_vaddr, SEEK_SET);
195 if (seek_ret != table_vaddr)
196 mpx_dig_abort();
197
198 int read_ret = read(fd, &bt_buf, sizeof(bt_buf));
199 if (read_ret != sizeof(bt_buf))
200 mpx_dig_abort();
201 return &bt_buf;
202#else
203 return (void *)table_vaddr;
204#endif
205}
206
207int dump_table(unsigned long table_vaddr, unsigned long base_controlled_vaddr,
208 unsigned long bde_vaddr)
209{
210 unsigned long offset_inside_bt;
211 int nr_entries = 0;
212 int do_abort = 0;
213 char *bt_buf;
214
215 dprintf3("%s() base_controlled_vaddr: 0x%012lx bde_vaddr: 0x%012lx\n",
216 __func__, base_controlled_vaddr, bde_vaddr);
217
218 bt_buf = read_bounds_table_into_buf(table_vaddr);
219
220 dprintf4("%s() read done\n", __func__);
221
222 for (offset_inside_bt = 0;
223 offset_inside_bt < MPX_BOUNDS_TABLE_SIZE_BYTES;
224 offset_inside_bt += bt_entry_size_bytes) {
225 unsigned long bt_entry_index;
226 unsigned long bt_entry_controls;
227 unsigned long this_bt_entry_for_vaddr;
228 unsigned long *bt_entry_buf;
229 int i;
230
231 dprintf4("%s() offset_inside_bt: 0x%lx of 0x%llx\n", __func__,
232 offset_inside_bt, MPX_BOUNDS_TABLE_SIZE_BYTES);
233 bt_entry_buf = (void *)&bt_buf[offset_inside_bt];
234 if (!bt_buf) {
235 printf("null bt_buf\n");
236 mpx_dig_abort();
237 }
238 if (!bt_entry_buf) {
239 printf("null bt_entry_buf\n");
240 mpx_dig_abort();
241 }
242 dprintf4("%s() reading *bt_entry_buf @ %p\n", __func__,
243 bt_entry_buf);
244 if (!bt_entry_buf[0] &&
245 !bt_entry_buf[1] &&
246 !bt_entry_buf[2] &&
247 !bt_entry_buf[3])
248 continue;
249
250 nr_entries++;
251
252 bt_entry_index = offset_inside_bt/bt_entry_size_bytes;
253 bt_entry_controls = sizeof(void *);
254 this_bt_entry_for_vaddr =
255 base_controlled_vaddr + bt_entry_index*bt_entry_controls;
256 /*
257 * We sign extend vaddr bits 48->63 which effectively
258 * creates a hole in the virtual address space.
259 * This calculation corrects for the hole.
260 */
261 if (this_bt_entry_for_vaddr > 0x00007fffffffffffUL)
262 this_bt_entry_for_vaddr |= 0xffff800000000000;
263
264 if (!vaddr_mapped_by_range(this_bt_entry_for_vaddr)) {
265 printf("bt_entry_buf: %p\n", bt_entry_buf);
266 printf("there is a bte for %lx but no mapping\n",
267 this_bt_entry_for_vaddr);
268 printf(" bde vaddr: %016lx\n", bde_vaddr);
269 printf("base_controlled_vaddr: %016lx\n", base_controlled_vaddr);
270 printf(" table_vaddr: %016lx\n", table_vaddr);
271 printf(" entry vaddr: %016lx @ offset %lx\n",
272 table_vaddr + offset_inside_bt, offset_inside_bt);
273 do_abort = 1;
274 mpx_dig_abort();
275 }
276 if (DEBUG_LEVEL < 4)
277 continue;
278
279 printf("table entry[%lx]: ", offset_inside_bt);
280 for (i = 0; i < bt_entry_size_bytes; i += sizeof(unsigned long))
281 printf("0x%016lx ", bt_entry_buf[i]);
282 printf("\n");
283 }
284 if (do_abort)
285 mpx_dig_abort();
286 dprintf4("%s() done\n", __func__);
287 return nr_entries;
288}
289
290int search_bd_buf(char *buf, int len_bytes, unsigned long bd_offset_bytes,
291 int *nr_populated_bdes)
292{
293 unsigned long i;
294 int total_entries = 0;
295
296 dprintf3("%s(%p, %x, %lx, ...) buf end: %p\n", __func__, buf,
297 len_bytes, bd_offset_bytes, buf + len_bytes);
298
299 for (i = 0; i < len_bytes; i += sizeof(unsigned long)) {
300 unsigned long bd_index = (bd_offset_bytes + i) / sizeof(unsigned long);
301 unsigned long *bounds_dir_entry_ptr = (unsigned long *)&buf[i];
302 unsigned long bounds_dir_entry;
303 unsigned long bd_for_vaddr;
304 unsigned long bt_start;
305 unsigned long bt_tail;
306 int nr_entries;
307
308 dprintf4("%s() loop i: %ld bounds_dir_entry_ptr: %p\n", __func__, i,
309 bounds_dir_entry_ptr);
310
311 bounds_dir_entry = *bounds_dir_entry_ptr;
312 if (!bounds_dir_entry) {
313 dprintf4("no bounds dir at index 0x%lx / 0x%lx "
314 "start at offset:%lx %lx\n", bd_index, bd_index,
315 bd_offset_bytes, i);
316 continue;
317 }
318 dprintf3("found bounds_dir_entry: 0x%lx @ "
319 "index 0x%lx buf ptr: %p\n", bounds_dir_entry, i,
320 &buf[i]);
321 /* mask off the enable bit: */
322 bounds_dir_entry &= ~0x1;
323 (*nr_populated_bdes)++;
324 dprintf4("nr_populated_bdes: %p\n", nr_populated_bdes);
325 dprintf4("*nr_populated_bdes: %d\n", *nr_populated_bdes);
326
327 bt_start = bounds_dir_entry;
328 bt_tail = bounds_dir_entry + MPX_BOUNDS_TABLE_SIZE_BYTES - 1;
329 if (!vaddr_mapped_by_range(bt_start)) {
330 printf("bounds directory 0x%lx points to nowhere\n",
331 bounds_dir_entry);
332 mpx_dig_abort();
333 }
334 if (!vaddr_mapped_by_range(bt_tail)) {
335 printf("bounds directory end 0x%lx points to nowhere\n",
336 bt_tail);
337 mpx_dig_abort();
338 }
339 /*
340 * Each bounds directory entry controls 1MB of virtual address
341 * space. This variable is the virtual address in the process
342 * of the beginning of the area controlled by this bounds_dir.
343 */
344 bd_for_vaddr = bd_index * (1UL<<20);
345
346 nr_entries = dump_table(bounds_dir_entry, bd_for_vaddr,
347 bounds_dir_global+bd_offset_bytes+i);
348 total_entries += nr_entries;
349 dprintf5("dir entry[%4ld @ %p]: 0x%lx %6d entries "
350 "total this buf: %7d bd_for_vaddrs: 0x%lx -> 0x%lx\n",
351 bd_index, buf+i,
352 bounds_dir_entry, nr_entries, total_entries,
353 bd_for_vaddr, bd_for_vaddr + (1UL<<20));
354 }
355 dprintf3("%s(%p, %x, %lx, ...) done\n", __func__, buf, len_bytes,
356 bd_offset_bytes);
357 return total_entries;
358}
359
360int proc_pid_mem_fd = -1;
361
362void *fill_bounds_dir_buf_other(long byte_offset_inside_bounds_dir,
363 long buffer_size_bytes, void *buffer)
364{
365 unsigned long seekto = bounds_dir_global + byte_offset_inside_bounds_dir;
366 int read_ret;
367 off_t seek_ret = lseek(proc_pid_mem_fd, seekto, SEEK_SET);
368
369 if (seek_ret != seekto)
370 mpx_dig_abort();
371
372 read_ret = read(proc_pid_mem_fd, buffer, buffer_size_bytes);
373 /* there shouldn't practically be short reads of /proc/$pid/mem */
374 if (read_ret != buffer_size_bytes)
375 mpx_dig_abort();
376
377 return buffer;
378}
379void *fill_bounds_dir_buf_self(long byte_offset_inside_bounds_dir,
380 long buffer_size_bytes, void *buffer)
381
382{
383 unsigned char vec[buffer_size_bytes / PAGE_SIZE];
384 char *dig_bounds_dir_ptr =
385 (void *)(bounds_dir_global + byte_offset_inside_bounds_dir);
386 /*
387 * use mincore() to quickly find the areas of the bounds directory
388 * that have memory and thus will be worth scanning.
389 */
390 int incore_ret;
391
392 int incore = 0;
393 int i;
394
395 dprintf4("%s() dig_bounds_dir_ptr: %p\n", __func__, dig_bounds_dir_ptr);
396
397 incore_ret = mincore(dig_bounds_dir_ptr, buffer_size_bytes, &vec[0]);
398 if (incore_ret) {
399 printf("mincore ret: %d\n", incore_ret);
400 perror("mincore");
401 mpx_dig_abort();
402 }
403 for (i = 0; i < sizeof(vec); i++)
404 incore += vec[i];
405 dprintf4("%s() total incore: %d\n", __func__, incore);
406 if (!incore)
407 return NULL;
408 dprintf3("%s() total incore: %d\n", __func__, incore);
409 return dig_bounds_dir_ptr;
410}
411
412int inspect_pid(int pid)
413{
414 static int dig_nr;
415 long offset_inside_bounds_dir;
416 char bounds_dir_buf[sizeof(unsigned long) * (1UL << 15)];
417 char *dig_bounds_dir_ptr;
418 int total_entries = 0;
419 int nr_populated_bdes = 0;
420 int inspect_self;
421
422 if (getpid() == pid) {
423 dprintf4("inspecting self\n");
424 inspect_self = 1;
425 } else {
426 dprintf4("inspecting pid %d\n", pid);
427 mpx_dig_abort();
428 }
429
430 for (offset_inside_bounds_dir = 0;
431 offset_inside_bounds_dir < MPX_BOUNDS_TABLE_SIZE_BYTES;
432 offset_inside_bounds_dir += sizeof(bounds_dir_buf)) {
433 static int bufs_skipped;
434 int this_entries;
435
436 if (inspect_self) {
437 dig_bounds_dir_ptr =
438 fill_bounds_dir_buf_self(offset_inside_bounds_dir,
439 sizeof(bounds_dir_buf),
440 &bounds_dir_buf[0]);
441 } else {
442 dig_bounds_dir_ptr =
443 fill_bounds_dir_buf_other(offset_inside_bounds_dir,
444 sizeof(bounds_dir_buf),
445 &bounds_dir_buf[0]);
446 }
447 if (!dig_bounds_dir_ptr) {
448 bufs_skipped++;
449 continue;
450 }
451 this_entries = search_bd_buf(dig_bounds_dir_ptr,
452 sizeof(bounds_dir_buf),
453 offset_inside_bounds_dir,
454 &nr_populated_bdes);
455 total_entries += this_entries;
456 }
457 printf("mpx dig (%3d) complete, SUCCESS (%8d / %4d)\n", ++dig_nr,
458 total_entries, nr_populated_bdes);
459 return total_entries + nr_populated_bdes;
460}
461
462#ifdef MPX_DIG_REMOTE
463int main(int argc, char **argv)
464{
465 int err;
466 char *c;
467 unsigned long bounds_dir_entry;
468 int pid;
469
470 printf("mpx-dig starting...\n");
471 err = sscanf(argv[1], "%d", &pid);
472 printf("parsing: '%s', err: %d\n", argv[1], err);
473 if (err != 1)
474 mpx_dig_abort();
475
476 err = sscanf(argv[2], "%lx", &bounds_dir_global);
477 printf("parsing: '%s': %d\n", argv[2], err);
478 if (err != 1)
479 mpx_dig_abort();
480
481 proc_pid_mem_fd = open_proc(pid, "mem");
482 if (proc_pid_mem_fd < 0)
483 mpx_dig_abort();
484
485 inspect_pid(pid);
486 return 0;
487}
488#endif
489
490long inspect_me(struct mpx_bounds_dir *bounds_dir)
491{
492 int pid = getpid();
493
494 pid_load_vaddrs(pid);
495 bounds_dir_global = (unsigned long)bounds_dir;
496 dprintf4("enter %s() bounds dir: %p\n", __func__, bounds_dir);
497 return inspect_pid(pid);
498}
diff --git a/tools/testing/selftests/x86/mpx-hw.h b/tools/testing/selftests/x86/mpx-hw.h
new file mode 100644
index 000000000000..093c190178a9
--- /dev/null
+++ b/tools/testing/selftests/x86/mpx-hw.h
@@ -0,0 +1,123 @@
1#ifndef _MPX_HW_H
2#define _MPX_HW_H
3
4#include <assert.h>
5
6/* Describe the MPX Hardware Layout in here */
7
8#define NR_MPX_BOUNDS_REGISTERS 4
9
10#ifdef __i386__
11
12#define MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES 16 /* 4 * 32-bits */
13#define MPX_BOUNDS_TABLE_SIZE_BYTES (1ULL << 14) /* 16k */
14#define MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES 4
15#define MPX_BOUNDS_DIR_SIZE_BYTES (1ULL << 22) /* 4MB */
16
17#define MPX_BOUNDS_TABLE_BOTTOM_BIT 2
18#define MPX_BOUNDS_TABLE_TOP_BIT 11
19#define MPX_BOUNDS_DIR_BOTTOM_BIT 12
20#define MPX_BOUNDS_DIR_TOP_BIT 31
21
22#else
23
24/*
25 * Linear Address of "pointer" (LAp)
26 * 0 -> 2: ignored
27 * 3 -> 19: index in to bounds table
28 * 20 -> 47: index in to bounds directory
29 * 48 -> 63: ignored
30 */
31
32#define MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES 32
33#define MPX_BOUNDS_TABLE_SIZE_BYTES (1ULL << 22) /* 4MB */
34#define MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES 8
35#define MPX_BOUNDS_DIR_SIZE_BYTES (1ULL << 31) /* 2GB */
36
37#define MPX_BOUNDS_TABLE_BOTTOM_BIT 3
38#define MPX_BOUNDS_TABLE_TOP_BIT 19
39#define MPX_BOUNDS_DIR_BOTTOM_BIT 20
40#define MPX_BOUNDS_DIR_TOP_BIT 47
41
42#endif
43
44#define MPX_BOUNDS_DIR_NR_ENTRIES \
45 (MPX_BOUNDS_DIR_SIZE_BYTES/MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES)
46#define MPX_BOUNDS_TABLE_NR_ENTRIES \
47 (MPX_BOUNDS_TABLE_SIZE_BYTES/MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES)
48
49#define MPX_BOUNDS_TABLE_ENTRY_VALID_BIT 0x1
50
51struct mpx_bd_entry {
52 union {
53 char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES];
54 void *contents[1];
55 };
56} __attribute__((packed));
57
58struct mpx_bt_entry {
59 union {
60 char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES];
61 unsigned long contents[1];
62 };
63} __attribute__((packed));
64
65struct mpx_bounds_dir {
66 struct mpx_bd_entry entries[MPX_BOUNDS_DIR_NR_ENTRIES];
67} __attribute__((packed));
68
69struct mpx_bounds_table {
70 struct mpx_bt_entry entries[MPX_BOUNDS_TABLE_NR_ENTRIES];
71} __attribute__((packed));
72
73static inline unsigned long GET_BITS(unsigned long val, int bottombit, int topbit)
74{
75 int total_nr_bits = topbit - bottombit;
76 unsigned long mask = (1UL << total_nr_bits)-1;
77 return (val >> bottombit) & mask;
78}
79
80static inline unsigned long __vaddr_bounds_table_index(void *vaddr)
81{
82 return GET_BITS((unsigned long)vaddr, MPX_BOUNDS_TABLE_BOTTOM_BIT,
83 MPX_BOUNDS_TABLE_TOP_BIT);
84}
85
86static inline unsigned long __vaddr_bounds_directory_index(void *vaddr)
87{
88 return GET_BITS((unsigned long)vaddr, MPX_BOUNDS_DIR_BOTTOM_BIT,
89 MPX_BOUNDS_DIR_TOP_BIT);
90}
91
92static inline struct mpx_bd_entry *mpx_vaddr_to_bd_entry(void *vaddr,
93 struct mpx_bounds_dir *bounds_dir)
94{
95 unsigned long index = __vaddr_bounds_directory_index(vaddr);
96 return &bounds_dir->entries[index];
97}
98
99static inline int bd_entry_valid(struct mpx_bd_entry *bounds_dir_entry)
100{
101 unsigned long __bd_entry = (unsigned long)bounds_dir_entry->contents;
102 return (__bd_entry & MPX_BOUNDS_TABLE_ENTRY_VALID_BIT);
103}
104
105static inline struct mpx_bounds_table *
106__bd_entry_to_bounds_table(struct mpx_bd_entry *bounds_dir_entry)
107{
108 unsigned long __bd_entry = (unsigned long)bounds_dir_entry->contents;
109 assert(__bd_entry & MPX_BOUNDS_TABLE_ENTRY_VALID_BIT);
110 __bd_entry &= ~MPX_BOUNDS_TABLE_ENTRY_VALID_BIT;
111 return (struct mpx_bounds_table *)__bd_entry;
112}
113
114static inline struct mpx_bt_entry *
115mpx_vaddr_to_bt_entry(void *vaddr, struct mpx_bounds_dir *bounds_dir)
116{
117 struct mpx_bd_entry *bde = mpx_vaddr_to_bd_entry(vaddr, bounds_dir);
118 struct mpx_bounds_table *bt = __bd_entry_to_bounds_table(bde);
119 unsigned long index = __vaddr_bounds_table_index(vaddr);
120 return &bt->entries[index];
121}
122
123#endif /* _MPX_HW_H */
diff --git a/tools/testing/selftests/x86/mpx-mini-test.c b/tools/testing/selftests/x86/mpx-mini-test.c
new file mode 100644
index 000000000000..616ee9673339
--- /dev/null
+++ b/tools/testing/selftests/x86/mpx-mini-test.c
@@ -0,0 +1,1585 @@
1/*
2 * mpx-mini-test.c: routines to test Intel MPX (Memory Protection eXtentions)
3 *
4 * Written by:
5 * "Ren, Qiaowei" <qiaowei.ren@intel.com>
6 * "Wei, Gang" <gang.wei@intel.com>
7 * "Hansen, Dave" <dave.hansen@intel.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2.
12 */
13
14/*
15 * 2014-12-05: Dave Hansen: fixed all of the compiler warnings, and made sure
16 * it works on 32-bit.
17 */
18
19int inspect_every_this_many_mallocs = 100;
20int zap_all_every_this_many_mallocs = 1000;
21
22#define _GNU_SOURCE
23#define _LARGEFILE64_SOURCE
24
25#include <string.h>
26#include <stdio.h>
27#include <stdint.h>
28#include <stdbool.h>
29#include <signal.h>
30#include <assert.h>
31#include <stdlib.h>
32#include <ucontext.h>
33#include <sys/mman.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <unistd.h>
38
39#include "mpx-hw.h"
40#include "mpx-debug.h"
41#include "mpx-mm.h"
42
43#ifndef __always_inline
44#define __always_inline inline __attribute__((always_inline)
45#endif
46
47#ifndef TEST_DURATION_SECS
48#define TEST_DURATION_SECS 3
49#endif
50
51void write_int_to(char *prefix, char *file, int int_to_write)
52{
53 char buf[100];
54 int fd = open(file, O_RDWR);
55 int len;
56 int ret;
57
58 assert(fd >= 0);
59 len = snprintf(buf, sizeof(buf), "%s%d", prefix, int_to_write);
60 assert(len >= 0);
61 assert(len < sizeof(buf));
62 ret = write(fd, buf, len);
63 assert(ret == len);
64 ret = close(fd);
65 assert(!ret);
66}
67
68void write_pid_to(char *prefix, char *file)
69{
70 write_int_to(prefix, file, getpid());
71}
72
73void trace_me(void)
74{
75/* tracing events dir */
76#define TED "/sys/kernel/debug/tracing/events/"
77/*
78 write_pid_to("common_pid=", TED "signal/filter");
79 write_pid_to("common_pid=", TED "exceptions/filter");
80 write_int_to("", TED "signal/enable", 1);
81 write_int_to("", TED "exceptions/enable", 1);
82*/
83 write_pid_to("", "/sys/kernel/debug/tracing/set_ftrace_pid");
84 write_int_to("", "/sys/kernel/debug/tracing/trace", 0);
85}
86
87#define test_failed() __test_failed(__FILE__, __LINE__)
88static void __test_failed(char *f, int l)
89{
90 fprintf(stderr, "abort @ %s::%d\n", f, l);
91 abort();
92}
93
94/* Error Printf */
95#define eprintf(args...) fprintf(stderr, args)
96
97#ifdef __i386__
98
99/* i386 directory size is 4MB */
100#define REG_IP_IDX REG_EIP
101#define REX_PREFIX
102
103#define XSAVE_OFFSET_IN_FPMEM sizeof(struct _libc_fpstate)
104
105/*
106 * __cpuid() is from the Linux Kernel:
107 */
108static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
109 unsigned int *ecx, unsigned int *edx)
110{
111 /* ecx is often an input as well as an output. */
112 asm volatile(
113 "push %%ebx;"
114 "cpuid;"
115 "mov %%ebx, %1;"
116 "pop %%ebx"
117 : "=a" (*eax),
118 "=g" (*ebx),
119 "=c" (*ecx),
120 "=d" (*edx)
121 : "0" (*eax), "2" (*ecx));
122}
123
124#else /* __i386__ */
125
126#define REG_IP_IDX REG_RIP
127#define REX_PREFIX "0x48, "
128
129#define XSAVE_OFFSET_IN_FPMEM 0
130
131/*
132 * __cpuid() is from the Linux Kernel:
133 */
134static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
135 unsigned int *ecx, unsigned int *edx)
136{
137 /* ecx is often an input as well as an output. */
138 asm volatile(
139 "cpuid;"
140 : "=a" (*eax),
141 "=b" (*ebx),
142 "=c" (*ecx),
143 "=d" (*edx)
144 : "0" (*eax), "2" (*ecx));
145}
146
147#endif /* !__i386__ */
148
149struct xsave_hdr_struct {
150 uint64_t xstate_bv;
151 uint64_t reserved1[2];
152 uint64_t reserved2[5];
153} __attribute__((packed));
154
155struct bndregs_struct {
156 uint64_t bndregs[8];
157} __attribute__((packed));
158
159struct bndcsr_struct {
160 uint64_t cfg_reg_u;
161 uint64_t status_reg;
162} __attribute__((packed));
163
164struct xsave_struct {
165 uint8_t fpu_sse[512];
166 struct xsave_hdr_struct xsave_hdr;
167 uint8_t ymm[256];
168 uint8_t lwp[128];
169 struct bndregs_struct bndregs;
170 struct bndcsr_struct bndcsr;
171} __attribute__((packed));
172
173uint8_t __attribute__((__aligned__(64))) buffer[4096];
174struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer;
175
176uint8_t __attribute__((__aligned__(64))) test_buffer[4096];
177struct xsave_struct *xsave_test_buf = (struct xsave_struct *)test_buffer;
178
179uint64_t num_bnd_chk;
180
181static __always_inline void xrstor_state(struct xsave_struct *fx, uint64_t mask)
182{
183 uint32_t lmask = mask;
184 uint32_t hmask = mask >> 32;
185
186 asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x2f\n\t"
187 : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask)
188 : "memory");
189}
190
191static __always_inline void xsave_state_1(void *_fx, uint64_t mask)
192{
193 uint32_t lmask = mask;
194 uint32_t hmask = mask >> 32;
195 unsigned char *fx = _fx;
196
197 asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x27\n\t"
198 : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask)
199 : "memory");
200}
201
202static inline uint64_t xgetbv(uint32_t index)
203{
204 uint32_t eax, edx;
205
206 asm volatile(".byte 0x0f,0x01,0xd0" /* xgetbv */
207 : "=a" (eax), "=d" (edx)
208 : "c" (index));
209 return eax + ((uint64_t)edx << 32);
210}
211
212static uint64_t read_mpx_status_sig(ucontext_t *uctxt)
213{
214 memset(buffer, 0, sizeof(buffer));
215 memcpy(buffer,
216 (uint8_t *)uctxt->uc_mcontext.fpregs + XSAVE_OFFSET_IN_FPMEM,
217 sizeof(struct xsave_struct));
218
219 return xsave_buf->bndcsr.status_reg;
220}
221
222#include <pthread.h>
223
224static uint8_t *get_next_inst_ip(uint8_t *addr)
225{
226 uint8_t *ip = addr;
227 uint8_t sib;
228 uint8_t rm;
229 uint8_t mod;
230 uint8_t base;
231 uint8_t modrm;
232
233 /* determine the prefix. */
234 switch(*ip) {
235 case 0xf2:
236 case 0xf3:
237 case 0x66:
238 ip++;
239 break;
240 }
241
242 /* look for rex prefix */
243 if ((*ip & 0x40) == 0x40)
244 ip++;
245
246 /* Make sure we have a MPX instruction. */
247 if (*ip++ != 0x0f)
248 return addr;
249
250 /* Skip the op code byte. */
251 ip++;
252
253 /* Get the modrm byte. */
254 modrm = *ip++;
255
256 /* Break it down into parts. */
257 rm = modrm & 7;
258 mod = (modrm >> 6);
259
260 /* Init the parts of the address mode. */
261 base = 8;
262
263 /* Is it a mem mode? */
264 if (mod != 3) {
265 /* look for scaled indexed addressing */
266 if (rm == 4) {
267 /* SIB addressing */
268 sib = *ip++;
269 base = sib & 7;
270 switch (mod) {
271 case 0:
272 if (base == 5)
273 ip += 4;
274 break;
275
276 case 1:
277 ip++;
278 break;
279
280 case 2:
281 ip += 4;
282 break;
283 }
284
285 } else {
286 /* MODRM addressing */
287 switch (mod) {
288 case 0:
289 /* DISP32 addressing, no base */
290 if (rm == 5)
291 ip += 4;
292 break;
293
294 case 1:
295 ip++;
296 break;
297
298 case 2:
299 ip += 4;
300 break;
301 }
302 }
303 }
304 return ip;
305}
306
307#ifdef si_lower
308static inline void *__si_bounds_lower(siginfo_t *si)
309{
310 return si->si_lower;
311}
312
313static inline void *__si_bounds_upper(siginfo_t *si)
314{
315 return si->si_upper;
316}
317#else
318static inline void **__si_bounds_hack(siginfo_t *si)
319{
320 void *sigfault = &si->_sifields._sigfault;
321 void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault);
322 void **__si_lower = end_sigfault;
323
324 return __si_lower;
325}
326
327static inline void *__si_bounds_lower(siginfo_t *si)
328{
329 return *__si_bounds_hack(si);
330}
331
332static inline void *__si_bounds_upper(siginfo_t *si)
333{
334 return (*__si_bounds_hack(si)) + sizeof(void *);
335}
336#endif
337
338static int br_count;
339static int expected_bnd_index = -1;
340uint64_t shadow_plb[NR_MPX_BOUNDS_REGISTERS][2]; /* shadow MPX bound registers */
341unsigned long shadow_map[NR_MPX_BOUNDS_REGISTERS];
342
343/*
344 * The kernel is supposed to provide some information about the bounds
345 * exception in the siginfo. It should match what we have in the bounds
346 * registers that we are checking against. Just check against the shadow copy
347 * since it is easily available, and we also check that *it* matches the real
348 * registers.
349 */
350void check_siginfo_vs_shadow(siginfo_t* si)
351{
352 int siginfo_ok = 1;
353 void *shadow_lower = (void *)(unsigned long)shadow_plb[expected_bnd_index][0];
354 void *shadow_upper = (void *)(unsigned long)shadow_plb[expected_bnd_index][1];
355
356 if ((expected_bnd_index < 0) ||
357 (expected_bnd_index >= NR_MPX_BOUNDS_REGISTERS)) {
358 fprintf(stderr, "ERROR: invalid expected_bnd_index: %d\n",
359 expected_bnd_index);
360 exit(6);
361 }
362 if (__si_bounds_lower(si) != shadow_lower)
363 siginfo_ok = 0;
364 if (__si_bounds_upper(si) != shadow_upper)
365 siginfo_ok = 0;
366
367 if (!siginfo_ok) {
368 fprintf(stderr, "ERROR: siginfo bounds do not match "
369 "shadow bounds for register %d\n", expected_bnd_index);
370 exit(7);
371 }
372}
373
374void handler(int signum, siginfo_t *si, void *vucontext)
375{
376 int i;
377 ucontext_t *uctxt = vucontext;
378 int trapno;
379 unsigned long ip;
380
381 dprintf1("entered signal handler\n");
382
383 trapno = uctxt->uc_mcontext.gregs[REG_TRAPNO];
384 ip = uctxt->uc_mcontext.gregs[REG_IP_IDX];
385
386 if (trapno == 5) {
387 typeof(si->si_addr) *si_addr_ptr = &si->si_addr;
388 uint64_t status = read_mpx_status_sig(uctxt);
389 uint64_t br_reason = status & 0x3;
390
391 br_count++;
392 dprintf1("#BR 0x%jx (total seen: %d)\n", status, br_count);
393
394#define __SI_FAULT (3 << 16)
395#define SEGV_BNDERR (__SI_FAULT|3) /* failed address bound checks */
396
397 dprintf2("Saw a #BR! status 0x%jx at %016lx br_reason: %jx\n",
398 status, ip, br_reason);
399 dprintf2("si_signo: %d\n", si->si_signo);
400 dprintf2(" signum: %d\n", signum);
401 dprintf2("info->si_code == SEGV_BNDERR: %d\n",
402 (si->si_code == SEGV_BNDERR));
403 dprintf2("info->si_code: %d\n", si->si_code);
404 dprintf2("info->si_lower: %p\n", __si_bounds_lower(si));
405 dprintf2("info->si_upper: %p\n", __si_bounds_upper(si));
406
407 check_siginfo_vs_shadow(si);
408
409 for (i = 0; i < 8; i++)
410 dprintf3("[%d]: %p\n", i, si_addr_ptr[i]);
411 switch (br_reason) {
412 case 0: /* traditional BR */
413 fprintf(stderr,
414 "Undefined status with bound exception:%jx\n",
415 status);
416 exit(5);
417 case 1: /* #BR MPX bounds exception */
418 /* these are normal and we expect to see them */
419 dprintf1("bounds exception (normal): status 0x%jx at %p si_addr: %p\n",
420 status, (void *)ip, si->si_addr);
421 num_bnd_chk++;
422 uctxt->uc_mcontext.gregs[REG_IP_IDX] =
423 (greg_t)get_next_inst_ip((uint8_t *)ip);
424 break;
425 case 2:
426 fprintf(stderr, "#BR status == 2, missing bounds table,"
427 "kernel should have handled!!\n");
428 exit(4);
429 break;
430 default:
431 fprintf(stderr, "bound check error: status 0x%jx at %p\n",
432 status, (void *)ip);
433 num_bnd_chk++;
434 uctxt->uc_mcontext.gregs[REG_IP_IDX] =
435 (greg_t)get_next_inst_ip((uint8_t *)ip);
436 fprintf(stderr, "bound check error: si_addr %p\n", si->si_addr);
437 exit(3);
438 }
439 } else if (trapno == 14) {
440 eprintf("ERROR: In signal handler, page fault, trapno = %d, ip = %016lx\n",
441 trapno, ip);
442 eprintf("si_addr %p\n", si->si_addr);
443 eprintf("REG_ERR: %lx\n", (unsigned long)uctxt->uc_mcontext.gregs[REG_ERR]);
444 test_failed();
445 } else {
446 eprintf("unexpected trap %d! at 0x%lx\n", trapno, ip);
447 eprintf("si_addr %p\n", si->si_addr);
448 eprintf("REG_ERR: %lx\n", (unsigned long)uctxt->uc_mcontext.gregs[REG_ERR]);
449 test_failed();
450 }
451}
452
453static inline void cpuid_count(unsigned int op, int count,
454 unsigned int *eax, unsigned int *ebx,
455 unsigned int *ecx, unsigned int *edx)
456{
457 *eax = op;
458 *ecx = count;
459 __cpuid(eax, ebx, ecx, edx);
460}
461
462#define XSTATE_CPUID 0x0000000d
463
464/*
465 * List of XSAVE features Linux knows about:
466 */
467enum xfeature_bit {
468 XSTATE_BIT_FP,
469 XSTATE_BIT_SSE,
470 XSTATE_BIT_YMM,
471 XSTATE_BIT_BNDREGS,
472 XSTATE_BIT_BNDCSR,
473 XSTATE_BIT_OPMASK,
474 XSTATE_BIT_ZMM_Hi256,
475 XSTATE_BIT_Hi16_ZMM,
476
477 XFEATURES_NR_MAX,
478};
479
480#define XSTATE_FP (1 << XSTATE_BIT_FP)
481#define XSTATE_SSE (1 << XSTATE_BIT_SSE)
482#define XSTATE_YMM (1 << XSTATE_BIT_YMM)
483#define XSTATE_BNDREGS (1 << XSTATE_BIT_BNDREGS)
484#define XSTATE_BNDCSR (1 << XSTATE_BIT_BNDCSR)
485#define XSTATE_OPMASK (1 << XSTATE_BIT_OPMASK)
486#define XSTATE_ZMM_Hi256 (1 << XSTATE_BIT_ZMM_Hi256)
487#define XSTATE_Hi16_ZMM (1 << XSTATE_BIT_Hi16_ZMM)
488
489#define MPX_XSTATES (XSTATE_BNDREGS | XSTATE_BNDCSR) /* 0x18 */
490
491bool one_bit(unsigned int x, int bit)
492{
493 return !!(x & (1<<bit));
494}
495
496void print_state_component(int state_bit_nr, char *name)
497{
498 unsigned int eax, ebx, ecx, edx;
499 unsigned int state_component_size;
500 unsigned int state_component_supervisor;
501 unsigned int state_component_user;
502 unsigned int state_component_aligned;
503
504 /* See SDM Section 13.2 */
505 cpuid_count(XSTATE_CPUID, state_bit_nr, &eax, &ebx, &ecx, &edx);
506 assert(eax || ebx || ecx);
507 state_component_size = eax;
508 state_component_supervisor = ((!ebx) && one_bit(ecx, 0));
509 state_component_user = !one_bit(ecx, 0);
510 state_component_aligned = one_bit(ecx, 1);
511 printf("%8s: size: %d user: %d supervisor: %d aligned: %d\n",
512 name,
513 state_component_size, state_component_user,
514 state_component_supervisor, state_component_aligned);
515
516}
517
518/* Intel-defined CPU features, CPUID level 0x00000001 (ecx) */
519#define XSAVE_FEATURE_BIT (26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
520#define OSXSAVE_FEATURE_BIT (27) /* XSAVE enabled in the OS */
521
522bool check_mpx_support(void)
523{
524 unsigned int eax, ebx, ecx, edx;
525
526 cpuid_count(1, 0, &eax, &ebx, &ecx, &edx);
527
528 /* We can't do much without XSAVE, so just make these assert()'s */
529 if (!one_bit(ecx, XSAVE_FEATURE_BIT)) {
530 fprintf(stderr, "processor lacks XSAVE, can not run MPX tests\n");
531 exit(0);
532 }
533
534 if (!one_bit(ecx, OSXSAVE_FEATURE_BIT)) {
535 fprintf(stderr, "processor lacks OSXSAVE, can not run MPX tests\n");
536 exit(0);
537 }
538
539 /* CPUs not supporting the XSTATE CPUID leaf do not support MPX */
540 /* Is this redundant with the feature bit checks? */
541 cpuid_count(0, 0, &eax, &ebx, &ecx, &edx);
542 if (eax < XSTATE_CPUID) {
543 fprintf(stderr, "processor lacks XSTATE CPUID leaf,"
544 " can not run MPX tests\n");
545 exit(0);
546 }
547
548 printf("XSAVE is supported by HW & OS\n");
549
550 cpuid_count(XSTATE_CPUID, 0, &eax, &ebx, &ecx, &edx);
551
552 printf("XSAVE processor supported state mask: 0x%x\n", eax);
553 printf("XSAVE OS supported state mask: 0x%jx\n", xgetbv(0));
554
555 /* Make sure that the MPX states are enabled in in XCR0 */
556 if ((eax & MPX_XSTATES) != MPX_XSTATES) {
557 fprintf(stderr, "processor lacks MPX XSTATE(s), can not run MPX tests\n");
558 exit(0);
559 }
560
561 /* Make sure the MPX states are supported by XSAVE* */
562 if ((xgetbv(0) & MPX_XSTATES) != MPX_XSTATES) {
563 fprintf(stderr, "MPX XSTATE(s) no enabled in XCR0, "
564 "can not run MPX tests\n");
565 exit(0);
566 }
567
568 print_state_component(XSTATE_BIT_BNDREGS, "BNDREGS");
569 print_state_component(XSTATE_BIT_BNDCSR, "BNDCSR");
570
571 return true;
572}
573
574void enable_mpx(void *l1base)
575{
576 /* enable point lookup */
577 memset(buffer, 0, sizeof(buffer));
578 xrstor_state(xsave_buf, 0x18);
579
580 xsave_buf->xsave_hdr.xstate_bv = 0x10;
581 xsave_buf->bndcsr.cfg_reg_u = (unsigned long)l1base | 1;
582 xsave_buf->bndcsr.status_reg = 0;
583
584 dprintf2("bf xrstor\n");
585 dprintf2("xsave cndcsr: status %jx, configu %jx\n",
586 xsave_buf->bndcsr.status_reg, xsave_buf->bndcsr.cfg_reg_u);
587 xrstor_state(xsave_buf, 0x18);
588 dprintf2("after xrstor\n");
589
590 xsave_state_1(xsave_buf, 0x18);
591
592 dprintf1("xsave bndcsr: status %jx, configu %jx\n",
593 xsave_buf->bndcsr.status_reg, xsave_buf->bndcsr.cfg_reg_u);
594}
595
596#include <sys/prctl.h>
597
598struct mpx_bounds_dir *bounds_dir_ptr;
599
600unsigned long __bd_incore(const char *func, int line)
601{
602 unsigned long ret = nr_incore(bounds_dir_ptr, MPX_BOUNDS_DIR_SIZE_BYTES);
603 return ret;
604}
605#define bd_incore() __bd_incore(__func__, __LINE__)
606
607void check_clear(void *ptr, unsigned long sz)
608{
609 unsigned long *i;
610
611 for (i = ptr; (void *)i < ptr + sz; i++) {
612 if (*i) {
613 dprintf1("%p is NOT clear at %p\n", ptr, i);
614 assert(0);
615 }
616 }
617 dprintf1("%p is clear for %lx\n", ptr, sz);
618}
619
620void check_clear_bd(void)
621{
622 check_clear(bounds_dir_ptr, 2UL << 30);
623}
624
625#define USE_MALLOC_FOR_BOUNDS_DIR 1
626bool process_specific_init(void)
627{
628 unsigned long size;
629 unsigned long *dir;
630 /* Guarantee we have the space to align it, add padding: */
631 unsigned long pad = getpagesize();
632
633 size = 2UL << 30; /* 2GB */
634 if (sizeof(unsigned long) == 4)
635 size = 4UL << 20; /* 4MB */
636 dprintf1("trying to allocate %ld MB bounds directory\n", (size >> 20));
637
638 if (USE_MALLOC_FOR_BOUNDS_DIR) {
639 unsigned long _dir;
640
641 dir = malloc(size + pad);
642 assert(dir);
643 _dir = (unsigned long)dir;
644 _dir += 0xfffUL;
645 _dir &= ~0xfffUL;
646 dir = (void *)_dir;
647 } else {
648 /*
649 * This makes debugging easier because the address
650 * calculations are simpler:
651 */
652 dir = mmap((void *)0x200000000000, size + pad,
653 PROT_READ|PROT_WRITE,
654 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
655 if (dir == (void *)-1) {
656 perror("unable to allocate bounds directory");
657 abort();
658 }
659 check_clear(dir, size);
660 }
661 bounds_dir_ptr = (void *)dir;
662 madvise(bounds_dir_ptr, size, MADV_NOHUGEPAGE);
663 bd_incore();
664 dprintf1("bounds directory: 0x%p -> 0x%p\n", bounds_dir_ptr,
665 (char *)bounds_dir_ptr + size);
666 check_clear(dir, size);
667 enable_mpx(dir);
668 check_clear(dir, size);
669 if (prctl(43, 0, 0, 0, 0)) {
670 printf("no MPX support\n");
671 abort();
672 return false;
673 }
674 return true;
675}
676
677bool process_specific_finish(void)
678{
679 if (prctl(44)) {
680 printf("no MPX support\n");
681 return false;
682 }
683 return true;
684}
685
686void setup_handler()
687{
688 int r, rs;
689 struct sigaction newact;
690 struct sigaction oldact;
691
692 /* #BR is mapped to sigsegv */
693 int signum = SIGSEGV;
694
695 newact.sa_handler = 0; /* void(*)(int)*/
696 newact.sa_sigaction = handler; /* void (*)(int, siginfo_t*, void *) */
697
698 /*sigset_t - signals to block while in the handler */
699 /* get the old signal mask. */
700 rs = sigprocmask(SIG_SETMASK, 0, &newact.sa_mask);
701 assert(rs == 0);
702
703 /* call sa_sigaction, not sa_handler*/
704 newact.sa_flags = SA_SIGINFO;
705
706 newact.sa_restorer = 0; /* void(*)(), obsolete */
707 r = sigaction(signum, &newact, &oldact);
708 assert(r == 0);
709}
710
711void mpx_prepare(void)
712{
713 dprintf2("%s()\n", __func__);
714 setup_handler();
715 process_specific_init();
716}
717
718void mpx_cleanup(void)
719{
720 printf("%s(): %jd BRs. bye...\n", __func__, num_bnd_chk);
721 process_specific_finish();
722}
723
724/*-------------- the following is test case ---------------*/
725#include <stdint.h>
726#include <stdbool.h>
727#include <stdlib.h>
728#include <stdio.h>
729#include <time.h>
730
731uint64_t num_lower_brs;
732uint64_t num_upper_brs;
733
734#define MPX_CONFIG_OFFSET 1024
735#define MPX_BOUNDS_OFFSET 960
736#define MPX_HEADER_OFFSET 512
737#define MAX_ADDR_TESTED (1<<28)
738#define TEST_ROUNDS 100
739
740/*
741 0F 1A /r BNDLDX-Load
742 0F 1B /r BNDSTX-Store Extended Bounds Using Address Translation
743 66 0F 1A /r BNDMOV bnd1, bnd2/m128
744 66 0F 1B /r BNDMOV bnd1/m128, bnd2
745 F2 0F 1A /r BNDCU bnd, r/m64
746 F2 0F 1B /r BNDCN bnd, r/m64
747 F3 0F 1A /r BNDCL bnd, r/m64
748 F3 0F 1B /r BNDMK bnd, m64
749*/
750
751static __always_inline void xsave_state(void *_fx, uint64_t mask)
752{
753 uint32_t lmask = mask;
754 uint32_t hmask = mask >> 32;
755 unsigned char *fx = _fx;
756
757 asm volatile(".byte " REX_PREFIX "0x0f,0xae,0x27\n\t"
758 : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask)
759 : "memory");
760}
761
762static __always_inline void mpx_clear_bnd0(void)
763{
764 long size = 0;
765 void *ptr = NULL;
766 /* F3 0F 1B /r BNDMK bnd, m64 */
767 /* f3 0f 1b 04 11 bndmk (%rcx,%rdx,1),%bnd0 */
768 asm volatile(".byte 0xf3,0x0f,0x1b,0x04,0x11\n\t"
769 : : "c" (ptr), "d" (size-1)
770 : "memory");
771}
772
773static __always_inline void mpx_make_bound_helper(unsigned long ptr,
774 unsigned long size)
775{
776 /* F3 0F 1B /r BNDMK bnd, m64 */
777 /* f3 0f 1b 04 11 bndmk (%rcx,%rdx,1),%bnd0 */
778 asm volatile(".byte 0xf3,0x0f,0x1b,0x04,0x11\n\t"
779 : : "c" (ptr), "d" (size-1)
780 : "memory");
781}
782
783static __always_inline void mpx_check_lowerbound_helper(unsigned long ptr)
784{
785 /* F3 0F 1A /r NDCL bnd, r/m64 */
786 /* f3 0f 1a 01 bndcl (%rcx),%bnd0 */
787 asm volatile(".byte 0xf3,0x0f,0x1a,0x01\n\t"
788 : : "c" (ptr)
789 : "memory");
790}
791
792static __always_inline void mpx_check_upperbound_helper(unsigned long ptr)
793{
794 /* F2 0F 1A /r BNDCU bnd, r/m64 */
795 /* f2 0f 1a 01 bndcu (%rcx),%bnd0 */
796 asm volatile(".byte 0xf2,0x0f,0x1a,0x01\n\t"
797 : : "c" (ptr)
798 : "memory");
799}
800
801static __always_inline void mpx_movbndreg_helper()
802{
803 /* 66 0F 1B /r BNDMOV bnd1/m128, bnd2 */
804 /* 66 0f 1b c2 bndmov %bnd0,%bnd2 */
805
806 asm volatile(".byte 0x66,0x0f,0x1b,0xc2\n\t");
807}
808
809static __always_inline void mpx_movbnd2mem_helper(uint8_t *mem)
810{
811 /* 66 0F 1B /r BNDMOV bnd1/m128, bnd2 */
812 /* 66 0f 1b 01 bndmov %bnd0,(%rcx) */
813 asm volatile(".byte 0x66,0x0f,0x1b,0x01\n\t"
814 : : "c" (mem)
815 : "memory");
816}
817
818static __always_inline void mpx_movbnd_from_mem_helper(uint8_t *mem)
819{
820 /* 66 0F 1A /r BNDMOV bnd1, bnd2/m128 */
821 /* 66 0f 1a 01 bndmov (%rcx),%bnd0 */
822 asm volatile(".byte 0x66,0x0f,0x1a,0x01\n\t"
823 : : "c" (mem)
824 : "memory");
825}
826
827static __always_inline void mpx_store_dsc_helper(unsigned long ptr_addr,
828 unsigned long ptr_val)
829{
830 /* 0F 1B /r BNDSTX-Store Extended Bounds Using Address Translation */
831 /* 0f 1b 04 11 bndstx %bnd0,(%rcx,%rdx,1) */
832 asm volatile(".byte 0x0f,0x1b,0x04,0x11\n\t"
833 : : "c" (ptr_addr), "d" (ptr_val)
834 : "memory");
835}
836
837static __always_inline void mpx_load_dsc_helper(unsigned long ptr_addr,
838 unsigned long ptr_val)
839{
840 /* 0F 1A /r BNDLDX-Load */
841 /*/ 0f 1a 04 11 bndldx (%rcx,%rdx,1),%bnd0 */
842 asm volatile(".byte 0x0f,0x1a,0x04,0x11\n\t"
843 : : "c" (ptr_addr), "d" (ptr_val)
844 : "memory");
845}
846
847void __print_context(void *__print_xsave_buffer, int line)
848{
849 uint64_t *bounds = (uint64_t *)(__print_xsave_buffer + MPX_BOUNDS_OFFSET);
850 uint64_t *cfg = (uint64_t *)(__print_xsave_buffer + MPX_CONFIG_OFFSET);
851
852 int i;
853 eprintf("%s()::%d\n", "print_context", line);
854 for (i = 0; i < 4; i++) {
855 eprintf("bound[%d]: 0x%016lx 0x%016lx(0x%016lx)\n", i,
856 (unsigned long)bounds[i*2],
857 ~(unsigned long)bounds[i*2+1],
858 (unsigned long)bounds[i*2+1]);
859 }
860
861 eprintf("cpcfg: %jx cpstatus: %jx\n", cfg[0], cfg[1]);
862}
863#define print_context(x) __print_context(x, __LINE__)
864#ifdef DEBUG
865#define dprint_context(x) print_context(x)
866#else
867#define dprint_context(x) do{}while(0)
868#endif
869
870void init()
871{
872 int i;
873
874 srand((unsigned int)time(NULL));
875
876 for (i = 0; i < 4; i++) {
877 shadow_plb[i][0] = 0;
878 shadow_plb[i][1] = ~(unsigned long)0;
879 }
880}
881
882long int __mpx_random(int line)
883{
884#ifdef NOT_SO_RANDOM
885 static long fake = 722122311;
886 fake += 563792075;
887 return fakse;
888#else
889 return random();
890#endif
891}
892#define mpx_random() __mpx_random(__LINE__)
893
894uint8_t *get_random_addr()
895{
896 uint8_t*addr = (uint8_t *)(unsigned long)(rand() % MAX_ADDR_TESTED);
897 return (addr - (unsigned long)addr % sizeof(uint8_t *));
898}
899
900static inline bool compare_context(void *__xsave_buffer)
901{
902 uint64_t *bounds = (uint64_t *)(__xsave_buffer + MPX_BOUNDS_OFFSET);
903
904 int i;
905 for (i = 0; i < 4; i++) {
906 dprintf3("shadow[%d]{%016lx/%016lx}\nbounds[%d]{%016lx/%016lx}\n",
907 i, (unsigned long)shadow_plb[i][0], (unsigned long)shadow_plb[i][1],
908 i, (unsigned long)bounds[i*2], ~(unsigned long)bounds[i*2+1]);
909 if ((shadow_plb[i][0] != bounds[i*2]) ||
910 (shadow_plb[i][1] != ~(unsigned long)bounds[i*2+1])) {
911 eprintf("ERROR comparing shadow to real bound register %d\n", i);
912 eprintf("shadow{0x%016lx/0x%016lx}\nbounds{0x%016lx/0x%016lx}\n",
913 (unsigned long)shadow_plb[i][0], (unsigned long)shadow_plb[i][1],
914 (unsigned long)bounds[i*2], (unsigned long)bounds[i*2+1]);
915 return false;
916 }
917 }
918
919 return true;
920}
921
922void mkbnd_shadow(uint8_t *ptr, int index, long offset)
923{
924 uint64_t *lower = (uint64_t *)&(shadow_plb[index][0]);
925 uint64_t *upper = (uint64_t *)&(shadow_plb[index][1]);
926 *lower = (unsigned long)ptr;
927 *upper = (unsigned long)ptr + offset - 1;
928}
929
930void check_lowerbound_shadow(uint8_t *ptr, int index)
931{
932 uint64_t *lower = (uint64_t *)&(shadow_plb[index][0]);
933 if (*lower > (uint64_t)(unsigned long)ptr)
934 num_lower_brs++;
935 else
936 dprintf1("LowerBoundChk passed:%p\n", ptr);
937}
938
939void check_upperbound_shadow(uint8_t *ptr, int index)
940{
941 uint64_t upper = *(uint64_t *)&(shadow_plb[index][1]);
942 if (upper < (uint64_t)(unsigned long)ptr)
943 num_upper_brs++;
944 else
945 dprintf1("UpperBoundChk passed:%p\n", ptr);
946}
947
948__always_inline void movbndreg_shadow(int src, int dest)
949{
950 shadow_plb[dest][0] = shadow_plb[src][0];
951 shadow_plb[dest][1] = shadow_plb[src][1];
952}
953
954__always_inline void movbnd2mem_shadow(int src, unsigned long *dest)
955{
956 unsigned long *lower = (unsigned long *)&(shadow_plb[src][0]);
957 unsigned long *upper = (unsigned long *)&(shadow_plb[src][1]);
958 *dest = *lower;
959 *(dest+1) = *upper;
960}
961
962__always_inline void movbnd_from_mem_shadow(unsigned long *src, int dest)
963{
964 unsigned long *lower = (unsigned long *)&(shadow_plb[dest][0]);
965 unsigned long *upper = (unsigned long *)&(shadow_plb[dest][1]);
966 *lower = *src;
967 *upper = *(src+1);
968}
969
970__always_inline void stdsc_shadow(int index, uint8_t *ptr, uint8_t *ptr_val)
971{
972 shadow_map[0] = (unsigned long)shadow_plb[index][0];
973 shadow_map[1] = (unsigned long)shadow_plb[index][1];
974 shadow_map[2] = (unsigned long)ptr_val;
975 dprintf3("%s(%d, %p, %p) set shadow map[2]: %p\n", __func__,
976 index, ptr, ptr_val, ptr_val);
977 /*ptr ignored */
978}
979
980void lddsc_shadow(int index, uint8_t *ptr, uint8_t *ptr_val)
981{
982 uint64_t lower = shadow_map[0];
983 uint64_t upper = shadow_map[1];
984 uint8_t *value = (uint8_t *)shadow_map[2];
985
986 if (value != ptr_val) {
987 dprintf2("%s(%d, %p, %p) init shadow bounds[%d] "
988 "because %p != %p\n", __func__, index, ptr,
989 ptr_val, index, value, ptr_val);
990 shadow_plb[index][0] = 0;
991 shadow_plb[index][1] = ~(unsigned long)0;
992 } else {
993 shadow_plb[index][0] = lower;
994 shadow_plb[index][1] = upper;
995 }
996 /* ptr ignored */
997}
998
999static __always_inline void mpx_test_helper0(uint8_t *buf, uint8_t *ptr)
1000{
1001 mpx_make_bound_helper((unsigned long)ptr, 0x1800);
1002}
1003
1004static __always_inline void mpx_test_helper0_shadow(uint8_t *buf, uint8_t *ptr)
1005{
1006 mkbnd_shadow(ptr, 0, 0x1800);
1007}
1008
1009static __always_inline void mpx_test_helper1(uint8_t *buf, uint8_t *ptr)
1010{
1011 /* these are hard-coded to check bnd0 */
1012 expected_bnd_index = 0;
1013 mpx_check_lowerbound_helper((unsigned long)(ptr-1));
1014 mpx_check_upperbound_helper((unsigned long)(ptr+0x1800));
1015 /* reset this since we do not expect any more bounds exceptions */
1016 expected_bnd_index = -1;
1017}
1018
1019static __always_inline void mpx_test_helper1_shadow(uint8_t *buf, uint8_t *ptr)
1020{
1021 check_lowerbound_shadow(ptr-1, 0);
1022 check_upperbound_shadow(ptr+0x1800, 0);
1023}
1024
1025static __always_inline void mpx_test_helper2(uint8_t *buf, uint8_t *ptr)
1026{
1027 mpx_make_bound_helper((unsigned long)ptr, 0x1800);
1028 mpx_movbndreg_helper();
1029 mpx_movbnd2mem_helper(buf);
1030 mpx_make_bound_helper((unsigned long)(ptr+0x12), 0x1800);
1031}
1032
1033static __always_inline void mpx_test_helper2_shadow(uint8_t *buf, uint8_t *ptr)
1034{
1035 mkbnd_shadow(ptr, 0, 0x1800);
1036 movbndreg_shadow(0, 2);
1037 movbnd2mem_shadow(0, (unsigned long *)buf);
1038 mkbnd_shadow(ptr+0x12, 0, 0x1800);
1039}
1040
1041static __always_inline void mpx_test_helper3(uint8_t *buf, uint8_t *ptr)
1042{
1043 mpx_movbnd_from_mem_helper(buf);
1044}
1045
1046static __always_inline void mpx_test_helper3_shadow(uint8_t *buf, uint8_t *ptr)
1047{
1048 movbnd_from_mem_shadow((unsigned long *)buf, 0);
1049}
1050
1051static __always_inline void mpx_test_helper4(uint8_t *buf, uint8_t *ptr)
1052{
1053 mpx_store_dsc_helper((unsigned long)buf, (unsigned long)ptr);
1054 mpx_make_bound_helper((unsigned long)(ptr+0x12), 0x1800);
1055}
1056
1057static __always_inline void mpx_test_helper4_shadow(uint8_t *buf, uint8_t *ptr)
1058{
1059 stdsc_shadow(0, buf, ptr);
1060 mkbnd_shadow(ptr+0x12, 0, 0x1800);
1061}
1062
1063static __always_inline void mpx_test_helper5(uint8_t *buf, uint8_t *ptr)
1064{
1065 mpx_load_dsc_helper((unsigned long)buf, (unsigned long)ptr);
1066}
1067
1068static __always_inline void mpx_test_helper5_shadow(uint8_t *buf, uint8_t *ptr)
1069{
1070 lddsc_shadow(0, buf, ptr);
1071}
1072
1073#define NR_MPX_TEST_FUNCTIONS 6
1074
1075/*
1076 * For compatibility reasons, MPX will clear the bounds registers
1077 * when you make function calls (among other things). We have to
1078 * preserve the registers in between calls to the "helpers" since
1079 * they build on each other.
1080 *
1081 * Be very careful not to make any function calls inside the
1082 * helpers, or anywhere else beween the xrstor and xsave.
1083 */
1084#define run_helper(helper_nr, buf, buf_shadow, ptr) do { \
1085 xrstor_state(xsave_test_buf, flags); \
1086 mpx_test_helper##helper_nr(buf, ptr); \
1087 xsave_state(xsave_test_buf, flags); \
1088 mpx_test_helper##helper_nr##_shadow(buf_shadow, ptr); \
1089} while (0)
1090
1091static void run_helpers(int nr, uint8_t *buf, uint8_t *buf_shadow, uint8_t *ptr)
1092{
1093 uint64_t flags = 0x18;
1094
1095 dprint_context(xsave_test_buf);
1096 switch (nr) {
1097 case 0:
1098 run_helper(0, buf, buf_shadow, ptr);
1099 break;
1100 case 1:
1101 run_helper(1, buf, buf_shadow, ptr);
1102 break;
1103 case 2:
1104 run_helper(2, buf, buf_shadow, ptr);
1105 break;
1106 case 3:
1107 run_helper(3, buf, buf_shadow, ptr);
1108 break;
1109 case 4:
1110 run_helper(4, buf, buf_shadow, ptr);
1111 break;
1112 case 5:
1113 run_helper(5, buf, buf_shadow, ptr);
1114 break;
1115 default:
1116 test_failed();
1117 break;
1118 }
1119 dprint_context(xsave_test_buf);
1120}
1121
1122unsigned long buf_shadow[1024]; /* used to check load / store descriptors */
1123extern long inspect_me(struct mpx_bounds_dir *bounds_dir);
1124
1125long cover_buf_with_bt_entries(void *buf, long buf_len)
1126{
1127 int i;
1128 long nr_to_fill;
1129 int ratio = 1000;
1130 unsigned long buf_len_in_ptrs;
1131
1132 /* Fill about 1/100 of the space with bt entries */
1133 nr_to_fill = buf_len / (sizeof(unsigned long) * ratio);
1134
1135 if (!nr_to_fill)
1136 dprintf3("%s() nr_to_fill: %ld\n", __func__, nr_to_fill);
1137
1138 /* Align the buffer to pointer size */
1139 while (((unsigned long)buf) % sizeof(void *)) {
1140 buf++;
1141 buf_len--;
1142 }
1143 /* We are storing pointers, so make */
1144 buf_len_in_ptrs = buf_len / sizeof(void *);
1145
1146 for (i = 0; i < nr_to_fill; i++) {
1147 long index = (mpx_random() % buf_len_in_ptrs);
1148 void *ptr = buf + index * sizeof(unsigned long);
1149 unsigned long ptr_addr = (unsigned long)ptr;
1150
1151 /* ptr and size can be anything */
1152 mpx_make_bound_helper((unsigned long)ptr, 8);
1153
1154 /*
1155 * take bnd0 and put it in to bounds tables "buf + index" is an
1156 * address inside the buffer where we are pretending that we
1157 * are going to put a pointer We do not, though because we will
1158 * never load entries from the table, so it doesn't matter.
1159 */
1160 mpx_store_dsc_helper(ptr_addr, (unsigned long)ptr);
1161 dprintf4("storing bound table entry for %lx (buf start @ %p)\n",
1162 ptr_addr, buf);
1163 }
1164 return nr_to_fill;
1165}
1166
1167unsigned long align_down(unsigned long alignme, unsigned long align_to)
1168{
1169 return alignme & ~(align_to-1);
1170}
1171
1172unsigned long align_up(unsigned long alignme, unsigned long align_to)
1173{
1174 return (alignme + align_to - 1) & ~(align_to-1);
1175}
1176
1177/*
1178 * Using 1MB alignment guarantees that each no allocation
1179 * will overlap with another's bounds tables.
1180 *
1181 * We have to cook our own allocator here. malloc() can
1182 * mix other allocation with ours which means that even
1183 * if we free all of our allocations, there might still
1184 * be bounds tables for the *areas* since there is other
1185 * valid memory there.
1186 *
1187 * We also can't use malloc() because a free() of an area
1188 * might not free it back to the kernel. We want it
1189 * completely unmapped an malloc() does not guarantee
1190 * that.
1191 */
1192#ifdef __i386__
1193long alignment = 4096;
1194long sz_alignment = 4096;
1195#else
1196long alignment = 1 * MB;
1197long sz_alignment = 1 * MB;
1198#endif
1199void *mpx_mini_alloc(unsigned long sz)
1200{
1201 unsigned long long tries = 0;
1202 static void *last;
1203 void *ptr;
1204 void *try_at;
1205
1206 sz = align_up(sz, sz_alignment);
1207
1208 try_at = last + alignment;
1209 while (1) {
1210 ptr = mmap(try_at, sz, PROT_READ|PROT_WRITE,
1211 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1212 if (ptr == (void *)-1)
1213 return NULL;
1214 if (ptr == try_at)
1215 break;
1216
1217 munmap(ptr, sz);
1218 try_at += alignment;
1219#ifdef __i386__
1220 /*
1221 * This isn't quite correct for 32-bit binaries
1222 * on 64-bit kernels since they can use the
1223 * entire 32-bit address space, but it's close
1224 * enough.
1225 */
1226 if (try_at > (void *)0xC0000000)
1227#else
1228 if (try_at > (void *)0x0000800000000000)
1229#endif
1230 try_at = (void *)0x0;
1231 if (!(++tries % 10000))
1232 dprintf1("stuck in %s(), tries: %lld\n", __func__, tries);
1233 continue;
1234 }
1235 last = ptr;
1236 dprintf3("mpx_mini_alloc(0x%lx) returning: %p\n", sz, ptr);
1237 return ptr;
1238}
1239void mpx_mini_free(void *ptr, long sz)
1240{
1241 dprintf2("%s() ptr: %p\n", __func__, ptr);
1242 if ((unsigned long)ptr > 0x100000000000) {
1243 dprintf1("uh oh !!!!!!!!!!!!!!! pointer too high: %p\n", ptr);
1244 test_failed();
1245 }
1246 sz = align_up(sz, sz_alignment);
1247 dprintf3("%s() ptr: %p before munmap\n", __func__, ptr);
1248 munmap(ptr, sz);
1249 dprintf3("%s() ptr: %p DONE\n", __func__, ptr);
1250}
1251
1252#define NR_MALLOCS 100
1253struct one_malloc {
1254 char *ptr;
1255 int nr_filled_btes;
1256 unsigned long size;
1257};
1258struct one_malloc mallocs[NR_MALLOCS];
1259
1260void free_one_malloc(int index)
1261{
1262 unsigned long free_ptr;
1263 unsigned long mask;
1264
1265 if (!mallocs[index].ptr)
1266 return;
1267
1268 mpx_mini_free(mallocs[index].ptr, mallocs[index].size);
1269 dprintf4("freed[%d]: %p\n", index, mallocs[index].ptr);
1270
1271 free_ptr = (unsigned long)mallocs[index].ptr;
1272 mask = alignment-1;
1273 dprintf4("lowerbits: %lx / %lx mask: %lx\n", free_ptr,
1274 (free_ptr & mask), mask);
1275 assert((free_ptr & mask) == 0);
1276
1277 mallocs[index].ptr = NULL;
1278}
1279
1280#ifdef __i386__
1281#define MPX_BOUNDS_TABLE_COVERS 4096
1282#else
1283#define MPX_BOUNDS_TABLE_COVERS (1 * MB)
1284#endif
1285void zap_everything(void)
1286{
1287 long after_zap;
1288 long before_zap;
1289 int i;
1290
1291 before_zap = inspect_me(bounds_dir_ptr);
1292 dprintf1("zapping everything start: %ld\n", before_zap);
1293 for (i = 0; i < NR_MALLOCS; i++)
1294 free_one_malloc(i);
1295
1296 after_zap = inspect_me(bounds_dir_ptr);
1297 dprintf1("zapping everything done: %ld\n", after_zap);
1298 /*
1299 * We only guarantee to empty the thing out if our allocations are
1300 * exactly aligned on the boundaries of a boudns table.
1301 */
1302 if ((alignment >= MPX_BOUNDS_TABLE_COVERS) &&
1303 (sz_alignment >= MPX_BOUNDS_TABLE_COVERS)) {
1304 if (after_zap != 0)
1305 test_failed();
1306
1307 assert(after_zap == 0);
1308 }
1309}
1310
1311void do_one_malloc(void)
1312{
1313 static int malloc_counter;
1314 long sz;
1315 int rand_index = (mpx_random() % NR_MALLOCS);
1316 void *ptr = mallocs[rand_index].ptr;
1317
1318 dprintf3("%s() enter\n", __func__);
1319
1320 if (ptr) {
1321 dprintf3("freeing one malloc at index: %d\n", rand_index);
1322 free_one_malloc(rand_index);
1323 if (mpx_random() % (NR_MALLOCS*3) == 3) {
1324 int i;
1325 dprintf3("zapping some more\n");
1326 for (i = rand_index; i < NR_MALLOCS; i++)
1327 free_one_malloc(i);
1328 }
1329 if ((mpx_random() % zap_all_every_this_many_mallocs) == 4)
1330 zap_everything();
1331 }
1332
1333 /* 1->~1M */
1334 sz = (1 + mpx_random() % 1000) * 1000;
1335 ptr = mpx_mini_alloc(sz);
1336 if (!ptr) {
1337 /*
1338 * If we are failing allocations, just assume we
1339 * are out of memory and zap everything.
1340 */
1341 dprintf3("zapping everything because out of memory\n");
1342 zap_everything();
1343 goto out;
1344 }
1345
1346 dprintf3("malloc: %p size: 0x%lx\n", ptr, sz);
1347 mallocs[rand_index].nr_filled_btes = cover_buf_with_bt_entries(ptr, sz);
1348 mallocs[rand_index].ptr = ptr;
1349 mallocs[rand_index].size = sz;
1350out:
1351 if ((++malloc_counter) % inspect_every_this_many_mallocs == 0)
1352 inspect_me(bounds_dir_ptr);
1353}
1354
1355void run_timed_test(void (*test_func)(void))
1356{
1357 int done = 0;
1358 long iteration = 0;
1359 static time_t last_print;
1360 time_t now;
1361 time_t start;
1362
1363 time(&start);
1364 while (!done) {
1365 time(&now);
1366 if ((now - start) > TEST_DURATION_SECS)
1367 done = 1;
1368
1369 test_func();
1370 iteration++;
1371
1372 if ((now - last_print > 1) || done) {
1373 printf("iteration %ld complete, OK so far\n", iteration);
1374 last_print = now;
1375 }
1376 }
1377}
1378
1379void check_bounds_table_frees(void)
1380{
1381 printf("executing unmaptest\n");
1382 inspect_me(bounds_dir_ptr);
1383 run_timed_test(&do_one_malloc);
1384 printf("done with malloc() fun\n");
1385}
1386
1387void insn_test_failed(int test_nr, int test_round, void *buf,
1388 void *buf_shadow, void *ptr)
1389{
1390 print_context(xsave_test_buf);
1391 eprintf("ERROR: test %d round %d failed\n", test_nr, test_round);
1392 while (test_nr == 5) {
1393 struct mpx_bt_entry *bte;
1394 struct mpx_bounds_dir *bd = (void *)bounds_dir_ptr;
1395 struct mpx_bd_entry *bde = mpx_vaddr_to_bd_entry(buf, bd);
1396
1397 printf(" bd: %p\n", bd);
1398 printf("&bde: %p\n", bde);
1399 printf("*bde: %lx\n", *(unsigned long *)bde);
1400 if (!bd_entry_valid(bde))
1401 break;
1402
1403 bte = mpx_vaddr_to_bt_entry(buf, bd);
1404 printf(" te: %p\n", bte);
1405 printf("bte[0]: %lx\n", bte->contents[0]);
1406 printf("bte[1]: %lx\n", bte->contents[1]);
1407 printf("bte[2]: %lx\n", bte->contents[2]);
1408 printf("bte[3]: %lx\n", bte->contents[3]);
1409 break;
1410 }
1411 test_failed();
1412}
1413
1414void check_mpx_insns_and_tables(void)
1415{
1416 int successes = 0;
1417 int failures = 0;
1418 int buf_size = (1024*1024);
1419 unsigned long *buf = malloc(buf_size);
1420 const int total_nr_tests = NR_MPX_TEST_FUNCTIONS * TEST_ROUNDS;
1421 int i, j;
1422
1423 memset(buf, 0, buf_size);
1424 memset(buf_shadow, 0, sizeof(buf_shadow));
1425
1426 for (i = 0; i < TEST_ROUNDS; i++) {
1427 uint8_t *ptr = get_random_addr() + 8;
1428
1429 for (j = 0; j < NR_MPX_TEST_FUNCTIONS; j++) {
1430 if (0 && j != 5) {
1431 successes++;
1432 continue;
1433 }
1434 dprintf2("starting test %d round %d\n", j, i);
1435 dprint_context(xsave_test_buf);
1436 /*
1437 * test5 loads an address from the bounds tables.
1438 * The load will only complete if 'ptr' matches
1439 * the load and the store, so with random addrs,
1440 * the odds of this are very small. Make it
1441 * higher by only moving 'ptr' 1/10 times.
1442 */
1443 if (random() % 10 <= 0)
1444 ptr = get_random_addr() + 8;
1445 dprintf3("random ptr{%p}\n", ptr);
1446 dprint_context(xsave_test_buf);
1447 run_helpers(j, (void *)buf, (void *)buf_shadow, ptr);
1448 dprint_context(xsave_test_buf);
1449 if (!compare_context(xsave_test_buf)) {
1450 insn_test_failed(j, i, buf, buf_shadow, ptr);
1451 failures++;
1452 goto exit;
1453 }
1454 successes++;
1455 dprint_context(xsave_test_buf);
1456 dprintf2("finished test %d round %d\n", j, i);
1457 dprintf3("\n");
1458 dprint_context(xsave_test_buf);
1459 }
1460 }
1461
1462exit:
1463 dprintf2("\nabout to free:\n");
1464 free(buf);
1465 dprintf1("successes: %d\n", successes);
1466 dprintf1(" failures: %d\n", failures);
1467 dprintf1(" tests: %d\n", total_nr_tests);
1468 dprintf1(" expected: %jd #BRs\n", num_upper_brs + num_lower_brs);
1469 dprintf1(" saw: %d #BRs\n", br_count);
1470 if (failures) {
1471 eprintf("ERROR: non-zero number of failures\n");
1472 exit(20);
1473 }
1474 if (successes != total_nr_tests) {
1475 eprintf("ERROR: succeded fewer than number of tries (%d != %d)\n",
1476 successes, total_nr_tests);
1477 exit(21);
1478 }
1479 if (num_upper_brs + num_lower_brs != br_count) {
1480 eprintf("ERROR: unexpected number of #BRs: %jd %jd %d\n",
1481 num_upper_brs, num_lower_brs, br_count);
1482 eprintf("successes: %d\n", successes);
1483 eprintf(" failures: %d\n", failures);
1484 eprintf(" tests: %d\n", total_nr_tests);
1485 eprintf(" expected: %jd #BRs\n", num_upper_brs + num_lower_brs);
1486 eprintf(" saw: %d #BRs\n", br_count);
1487 exit(22);
1488 }
1489}
1490
1491/*
1492 * This is supposed to SIGSEGV nicely once the kernel
1493 * can no longer allocate vaddr space.
1494 */
1495void exhaust_vaddr_space(void)
1496{
1497 unsigned long ptr;
1498 /* Try to make sure there is no room for a bounds table anywhere */
1499 unsigned long skip = MPX_BOUNDS_TABLE_SIZE_BYTES - PAGE_SIZE;
1500#ifdef __i386__
1501 unsigned long max_vaddr = 0xf7788000UL;
1502#else
1503 unsigned long max_vaddr = 0x800000000000UL;
1504#endif
1505
1506 dprintf1("%s() start\n", __func__);
1507 /* do not start at 0, we aren't allowed to map there */
1508 for (ptr = PAGE_SIZE; ptr < max_vaddr; ptr += skip) {
1509 void *ptr_ret;
1510 int ret = madvise((void *)ptr, PAGE_SIZE, MADV_NORMAL);
1511
1512 if (!ret) {
1513 dprintf1("madvise() %lx ret: %d\n", ptr, ret);
1514 continue;
1515 }
1516 ptr_ret = mmap((void *)ptr, PAGE_SIZE, PROT_READ|PROT_WRITE,
1517 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1518 if (ptr_ret != (void *)ptr) {
1519 perror("mmap");
1520 dprintf1("mmap(%lx) ret: %p\n", ptr, ptr_ret);
1521 break;
1522 }
1523 if (!(ptr & 0xffffff))
1524 dprintf1("mmap(%lx) ret: %p\n", ptr, ptr_ret);
1525 }
1526 for (ptr = PAGE_SIZE; ptr < max_vaddr; ptr += skip) {
1527 dprintf2("covering 0x%lx with bounds table entries\n", ptr);
1528 cover_buf_with_bt_entries((void *)ptr, PAGE_SIZE);
1529 }
1530 dprintf1("%s() end\n", __func__);
1531 printf("done with vaddr space fun\n");
1532}
1533
1534void mpx_table_test(void)
1535{
1536 printf("starting mpx bounds table test\n");
1537 run_timed_test(check_mpx_insns_and_tables);
1538 printf("done with mpx bounds table test\n");
1539}
1540
1541int main(int argc, char **argv)
1542{
1543 int unmaptest = 0;
1544 int vaddrexhaust = 0;
1545 int tabletest = 0;
1546 int i;
1547
1548 check_mpx_support();
1549 mpx_prepare();
1550 srandom(11179);
1551
1552 bd_incore();
1553 init();
1554 bd_incore();
1555
1556 trace_me();
1557
1558 xsave_state((void *)xsave_test_buf, 0x1f);
1559 if (!compare_context(xsave_test_buf))
1560 printf("Init failed\n");
1561
1562 for (i = 1; i < argc; i++) {
1563 if (!strcmp(argv[i], "unmaptest"))
1564 unmaptest = 1;
1565 if (!strcmp(argv[i], "vaddrexhaust"))
1566 vaddrexhaust = 1;
1567 if (!strcmp(argv[i], "tabletest"))
1568 tabletest = 1;
1569 }
1570 if (!(unmaptest || vaddrexhaust || tabletest)) {
1571 unmaptest = 1;
1572 /* vaddrexhaust = 1; */
1573 tabletest = 1;
1574 }
1575 if (unmaptest)
1576 check_bounds_table_frees();
1577 if (tabletest)
1578 mpx_table_test();
1579 if (vaddrexhaust)
1580 exhaust_vaddr_space();
1581 printf("%s completed successfully\n", argv[0]);
1582 exit(0);
1583}
1584
1585#include "mpx-dig.c"
diff --git a/tools/testing/selftests/x86/mpx-mm.h b/tools/testing/selftests/x86/mpx-mm.h
new file mode 100644
index 000000000000..af706a5398f7
--- /dev/null
+++ b/tools/testing/selftests/x86/mpx-mm.h
@@ -0,0 +1,9 @@
1#ifndef _MPX_MM_H
2#define _MPX_MM_H
3
4#define PAGE_SIZE 4096
5#define MB (1UL<<20)
6
7extern long nr_incore(void *ptr, unsigned long size_bytes);
8
9#endif /* _MPX_MM_H */
diff --git a/tools/testing/selftests/x86/test_mremap_vdso.c b/tools/testing/selftests/x86/test_mremap_vdso.c
new file mode 100644
index 000000000000..bf0d687c7db7
--- /dev/null
+++ b/tools/testing/selftests/x86/test_mremap_vdso.c
@@ -0,0 +1,111 @@
1/*
2 * 32-bit test to check vDSO mremap.
3 *
4 * Copyright (c) 2016 Dmitry Safonov
5 * Suggested-by: Andrew Lutomirski
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16/*
17 * Can be built statically:
18 * gcc -Os -Wall -static -m32 test_mremap_vdso.c
19 */
20#define _GNU_SOURCE
21#include <stdio.h>
22#include <errno.h>
23#include <unistd.h>
24#include <string.h>
25
26#include <sys/mman.h>
27#include <sys/auxv.h>
28#include <sys/syscall.h>
29#include <sys/wait.h>
30
31#define PAGE_SIZE 4096
32
33static int try_to_remap(void *vdso_addr, unsigned long size)
34{
35 void *dest_addr, *new_addr;
36
37 /* Searching for memory location where to remap */
38 dest_addr = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
39 if (dest_addr == MAP_FAILED) {
40 printf("[WARN]\tmmap failed (%d): %m\n", errno);
41 return 0;
42 }
43
44 printf("[NOTE]\tMoving vDSO: [%p, %#lx] -> [%p, %#lx]\n",
45 vdso_addr, (unsigned long)vdso_addr + size,
46 dest_addr, (unsigned long)dest_addr + size);
47 fflush(stdout);
48
49 new_addr = mremap(vdso_addr, size, size,
50 MREMAP_FIXED|MREMAP_MAYMOVE, dest_addr);
51 if ((unsigned long)new_addr == (unsigned long)-1) {
52 munmap(dest_addr, size);
53 if (errno == EINVAL) {
54 printf("[NOTE]\tvDSO partial move failed, will try with bigger size\n");
55 return -1; /* Retry with larger */
56 }
57 printf("[FAIL]\tmremap failed (%d): %m\n", errno);
58 return 1;
59 }
60
61 return 0;
62
63}
64
65int main(int argc, char **argv, char **envp)
66{
67 pid_t child;
68
69 child = fork();
70 if (child == -1) {
71 printf("[WARN]\tfailed to fork (%d): %m\n", errno);
72 return 1;
73 }
74
75 if (child == 0) {
76 unsigned long vdso_size = PAGE_SIZE;
77 unsigned long auxval;
78 int ret = -1;
79
80 auxval = getauxval(AT_SYSINFO_EHDR);
81 printf("\tAT_SYSINFO_EHDR is %#lx\n", auxval);
82 if (!auxval || auxval == -ENOENT) {
83 printf("[WARN]\tgetauxval failed\n");
84 return 0;
85 }
86
87 /* Simpler than parsing ELF header */
88 while (ret < 0) {
89 ret = try_to_remap((void *)auxval, vdso_size);
90 vdso_size += PAGE_SIZE;
91 }
92
93 /* Glibc is likely to explode now - exit with raw syscall */
94 asm volatile ("int $0x80" : : "a" (__NR_exit), "b" (!!ret));
95 } else {
96 int status;
97
98 if (waitpid(child, &status, 0) != child ||
99 !WIFEXITED(status)) {
100 printf("[FAIL]\tmremap() of the vDSO does not work on this kernel!\n");
101 return 1;
102 } else if (WEXITSTATUS(status) != 0) {
103 printf("[FAIL]\tChild failed with %d\n",
104 WEXITSTATUS(status));
105 return 1;
106 }
107 printf("[OK]\n");
108 }
109
110 return 0;
111}
diff --git a/tools/virtio/ringtest/Makefile b/tools/virtio/ringtest/Makefile
index 6173adae9f08..877a8a4721b6 100644
--- a/tools/virtio/ringtest/Makefile
+++ b/tools/virtio/ringtest/Makefile
@@ -1,6 +1,6 @@
1all: 1all:
2 2
3all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder noring 3all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder ptr_ring noring
4 4
5CFLAGS += -Wall 5CFLAGS += -Wall
6CFLAGS += -pthread -O2 -ggdb 6CFLAGS += -pthread -O2 -ggdb
@@ -8,6 +8,7 @@ LDFLAGS += -pthread -O2 -ggdb
8 8
9main.o: main.c main.h 9main.o: main.c main.h
10ring.o: ring.c main.h 10ring.o: ring.c main.h
11ptr_ring.o: ptr_ring.c main.h ../../../include/linux/ptr_ring.h
11virtio_ring_0_9.o: virtio_ring_0_9.c main.h 12virtio_ring_0_9.o: virtio_ring_0_9.c main.h
12virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h 13virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h
13virtio_ring_inorder.o: virtio_ring_inorder.c virtio_ring_0_9.c main.h 14virtio_ring_inorder.o: virtio_ring_inorder.c virtio_ring_0_9.c main.h
@@ -15,6 +16,7 @@ ring: ring.o main.o
15virtio_ring_0_9: virtio_ring_0_9.o main.o 16virtio_ring_0_9: virtio_ring_0_9.o main.o
16virtio_ring_poll: virtio_ring_poll.o main.o 17virtio_ring_poll: virtio_ring_poll.o main.o
17virtio_ring_inorder: virtio_ring_inorder.o main.o 18virtio_ring_inorder: virtio_ring_inorder.o main.o
19ptr_ring: ptr_ring.o main.o
18noring: noring.o main.o 20noring: noring.o main.o
19clean: 21clean:
20 -rm main.o 22 -rm main.o
@@ -22,6 +24,7 @@ clean:
22 -rm virtio_ring_0_9.o virtio_ring_0_9 24 -rm virtio_ring_0_9.o virtio_ring_0_9
23 -rm virtio_ring_poll.o virtio_ring_poll 25 -rm virtio_ring_poll.o virtio_ring_poll
24 -rm virtio_ring_inorder.o virtio_ring_inorder 26 -rm virtio_ring_inorder.o virtio_ring_inorder
27 -rm ptr_ring.o ptr_ring
25 -rm noring.o noring 28 -rm noring.o noring
26 29
27.PHONY: all clean 30.PHONY: all clean
diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c
new file mode 100644
index 000000000000..68e4f9f0da3a
--- /dev/null
+++ b/tools/virtio/ringtest/ptr_ring.c
@@ -0,0 +1,197 @@
1#define _GNU_SOURCE
2#include "main.h"
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6#include <pthread.h>
7#include <malloc.h>
8#include <assert.h>
9#include <errno.h>
10#include <limits.h>
11
12#define SMP_CACHE_BYTES 64
13#define cache_line_size() SMP_CACHE_BYTES
14#define ____cacheline_aligned_in_smp __attribute__ ((aligned (SMP_CACHE_BYTES)))
15#define unlikely(x) (__builtin_expect(!!(x), 0))
16#define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a))
17typedef pthread_spinlock_t spinlock_t;
18
19typedef int gfp_t;
20static void *kmalloc(unsigned size, gfp_t gfp)
21{
22 return memalign(64, size);
23}
24
25static void *kzalloc(unsigned size, gfp_t gfp)
26{
27 void *p = memalign(64, size);
28 if (!p)
29 return p;
30 memset(p, 0, size);
31
32 return p;
33}
34
35static void kfree(void *p)
36{
37 if (p)
38 free(p);
39}
40
41static void spin_lock_init(spinlock_t *lock)
42{
43 int r = pthread_spin_init(lock, 0);
44 assert(!r);
45}
46
47static void spin_lock(spinlock_t *lock)
48{
49 int ret = pthread_spin_lock(lock);
50 assert(!ret);
51}
52
53static void spin_unlock(spinlock_t *lock)
54{
55 int ret = pthread_spin_unlock(lock);
56 assert(!ret);
57}
58
59static void spin_lock_bh(spinlock_t *lock)
60{
61 spin_lock(lock);
62}
63
64static void spin_unlock_bh(spinlock_t *lock)
65{
66 spin_unlock(lock);
67}
68
69static void spin_lock_irq(spinlock_t *lock)
70{
71 spin_lock(lock);
72}
73
74static void spin_unlock_irq(spinlock_t *lock)
75{
76 spin_unlock(lock);
77}
78
79static void spin_lock_irqsave(spinlock_t *lock, unsigned long f)
80{
81 spin_lock(lock);
82}
83
84static void spin_unlock_irqrestore(spinlock_t *lock, unsigned long f)
85{
86 spin_unlock(lock);
87}
88
89#include "../../../include/linux/ptr_ring.h"
90
91static unsigned long long headcnt, tailcnt;
92static struct ptr_ring array ____cacheline_aligned_in_smp;
93
94/* implemented by ring */
95void alloc_ring(void)
96{
97 int ret = ptr_ring_init(&array, ring_size, 0);
98 assert(!ret);
99}
100
101/* guest side */
102int add_inbuf(unsigned len, void *buf, void *datap)
103{
104 int ret;
105
106 ret = __ptr_ring_produce(&array, buf);
107 if (ret >= 0) {
108 ret = 0;
109 headcnt++;
110 }
111
112 return ret;
113}
114
115/*
116 * ptr_ring API provides no way for producer to find out whether a given
117 * buffer was consumed. Our tests merely require that a successful get_buf
118 * implies that add_inbuf succeed in the past, and that add_inbuf will succeed,
119 * fake it accordingly.
120 */
121void *get_buf(unsigned *lenp, void **bufp)
122{
123 void *datap;
124
125 if (tailcnt == headcnt || __ptr_ring_full(&array))
126 datap = NULL;
127 else {
128 datap = "Buffer\n";
129 ++tailcnt;
130 }
131
132 return datap;
133}
134
135void poll_used(void)
136{
137 void *b;
138
139 do {
140 if (tailcnt == headcnt || __ptr_ring_full(&array)) {
141 b = NULL;
142 barrier();
143 } else {
144 b = "Buffer\n";
145 }
146 } while (!b);
147}
148
149void disable_call()
150{
151 assert(0);
152}
153
154bool enable_call()
155{
156 assert(0);
157}
158
159void kick_available(void)
160{
161 assert(0);
162}
163
164/* host side */
165void disable_kick()
166{
167 assert(0);
168}
169
170bool enable_kick()
171{
172 assert(0);
173}
174
175void poll_avail(void)
176{
177 void *b;
178
179 do {
180 barrier();
181 b = __ptr_ring_peek(&array);
182 } while (!b);
183}
184
185bool use_buf(unsigned *lenp, void **bufp)
186{
187 void *ptr;
188
189 ptr = __ptr_ring_consume(&array);
190
191 return ptr;
192}
193
194void call_used(void)
195{
196 assert(0);
197}
diff --git a/tools/vm/page_owner_sort.c b/tools/vm/page_owner_sort.c
index 77147b42d598..f1c055f3c243 100644
--- a/tools/vm/page_owner_sort.c
+++ b/tools/vm/page_owner_sort.c
@@ -79,12 +79,12 @@ static void add_list(char *buf, int len)
79 } 79 }
80} 80}
81 81
82#define BUF_SIZE 1024 82#define BUF_SIZE (128 * 1024)
83 83
84int main(int argc, char **argv) 84int main(int argc, char **argv)
85{ 85{
86 FILE *fin, *fout; 86 FILE *fin, *fout;
87 char buf[BUF_SIZE]; 87 char *buf;
88 int ret, i, count; 88 int ret, i, count;
89 struct block_list *list2; 89 struct block_list *list2;
90 struct stat st; 90 struct stat st;
@@ -107,6 +107,11 @@ int main(int argc, char **argv)
107 max_size = st.st_size / 100; /* hack ... */ 107 max_size = st.st_size / 100; /* hack ... */
108 108
109 list = malloc(max_size * sizeof(*list)); 109 list = malloc(max_size * sizeof(*list));
110 buf = malloc(BUF_SIZE);
111 if (!list || !buf) {
112 printf("Out of memory\n");
113 exit(1);
114 }
110 115
111 for ( ; ; ) { 116 for ( ; ; ) {
112 ret = read_block(buf, BUF_SIZE, fin); 117 ret = read_block(buf, BUF_SIZE, fin);