aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/intel-pt.txt59
-rw-r--r--tools/perf/Documentation/itrace.txt4
-rw-r--r--tools/perf/Documentation/perf-bench.txt54
-rw-r--r--tools/perf/Documentation/perf-inject.txt3
-rw-r--r--tools/perf/Documentation/perf-list.txt3
-rw-r--r--tools/perf/Documentation/perf-record.txt16
-rw-r--r--tools/perf/Documentation/perf-report.txt48
-rw-r--r--tools/perf/Documentation/perf-script.txt17
-rw-r--r--tools/perf/Documentation/perf-stat.txt5
-rw-r--r--tools/perf/Documentation/perf-top.txt5
-rw-r--r--tools/perf/Documentation/perf.txt8
-rw-r--r--tools/perf/MANIFEST5
-rw-r--r--tools/perf/Makefile.perf53
-rw-r--r--tools/perf/arch/common.c10
-rw-r--r--tools/perf/arch/common.h4
-rw-r--r--tools/perf/arch/x86/Build2
-rw-r--r--tools/perf/arch/x86/Makefile1
-rw-r--r--tools/perf/arch/x86/include/arch-tests.h19
-rw-r--r--tools/perf/arch/x86/tests/Build10
-rw-r--r--tools/perf/arch/x86/tests/arch-tests.c34
-rw-r--r--tools/perf/arch/x86/tests/dwarf-unwind.c1
-rw-r--r--tools/perf/arch/x86/tests/gen-insn-x86-dat.awk75
-rwxr-xr-xtools/perf/arch/x86/tests/gen-insn-x86-dat.sh43
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-32.c658
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-64.c768
-rw-r--r--tools/perf/arch/x86/tests/insn-x86-dat-src.c877
-rw-r--r--tools/perf/arch/x86/tests/insn-x86.c185
-rw-r--r--tools/perf/arch/x86/tests/intel-cqm.c124
-rw-r--r--tools/perf/arch/x86/tests/perf-time-to-tsc.c (renamed from tools/perf/tests/perf-time-to-tsc.c)4
-rw-r--r--tools/perf/arch/x86/tests/rdpmc.c (renamed from tools/perf/tests/rdpmc.c)7
-rw-r--r--tools/perf/arch/x86/util/dwarf-regs.c122
-rw-r--r--tools/perf/arch/x86/util/intel-pt.c55
-rw-r--r--tools/perf/bench/Build2
-rw-r--r--tools/perf/bench/mem-functions.c379
-rw-r--r--tools/perf/bench/mem-memcpy.c434
-rw-r--r--tools/perf/bench/numa.c4
-rw-r--r--tools/perf/bench/sched-messaging.c10
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-bench.c14
-rw-r--r--tools/perf/builtin-evlist.c4
-rw-r--r--tools/perf/builtin-help.c2
-rw-r--r--tools/perf/builtin-inject.c127
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/builtin-kvm.c1
-rw-r--r--tools/perf/builtin-list.c20
-rw-r--r--tools/perf/builtin-probe.c147
-rw-r--r--tools/perf/builtin-record.c56
-rw-r--r--tools/perf/builtin-report.c65
-rw-r--r--tools/perf/builtin-sched.c4
-rw-r--r--tools/perf/builtin-script.c117
-rw-r--r--tools/perf/builtin-stat.c93
-rw-r--r--tools/perf/builtin-top.c59
-rw-r--r--tools/perf/builtin-trace.c31
-rw-r--r--tools/perf/config/Makefile43
-rw-r--r--tools/perf/perf.c30
-rwxr-xr-xtools/perf/python/twatch.py23
-rw-r--r--tools/perf/scripts/python/export-to-postgresql.py221
-rw-r--r--tools/perf/tests/Build4
-rw-r--r--tools/perf/tests/bpf-script-example.c44
-rw-r--r--tools/perf/tests/builtin-test.c76
-rw-r--r--tools/perf/tests/code-reading.c76
-rw-r--r--tools/perf/tests/dwarf-unwind.c4
-rw-r--r--tools/perf/tests/evsel-tp-sched.c10
-rw-r--r--tools/perf/tests/hists_filter.c55
-rw-r--r--tools/perf/tests/make4
-rw-r--r--tools/perf/tests/mmap-basic.c3
-rw-r--r--tools/perf/tests/openat-syscall-all-cpus.c13
-rw-r--r--tools/perf/tests/openat-syscall-tp-fields.c5
-rw-r--r--tools/perf/tests/openat-syscall.c13
-rw-r--r--tools/perf/tests/parse-events.c49
-rw-r--r--tools/perf/tests/sw-clock.c18
-rw-r--r--tools/perf/tests/task-exit.c18
-rw-r--r--tools/perf/tests/tests.h10
-rw-r--r--tools/perf/tests/topology.c115
-rw-r--r--tools/perf/tests/vmlinux-kallsyms.c4
-rw-r--r--tools/perf/trace/strace/groups/file2
-rw-r--r--tools/perf/ui/browser.c14
-rw-r--r--tools/perf/ui/browser.h2
-rw-r--r--tools/perf/ui/browsers/annotate.c14
-rw-r--r--tools/perf/ui/browsers/hists.c132
-rw-r--r--tools/perf/ui/browsers/map.c2
-rw-r--r--tools/perf/ui/browsers/scripts.c2
-rw-r--r--tools/perf/ui/hist.c16
-rw-r--r--tools/perf/ui/tui/setup.c8
-rw-r--r--tools/perf/util/Build4
-rw-r--r--tools/perf/util/annotate.c5
-rw-r--r--tools/perf/util/annotate.h2
-rw-r--r--tools/perf/util/auxtrace.c24
-rw-r--r--tools/perf/util/auxtrace.h4
-rw-r--r--tools/perf/util/bpf-loader.c352
-rw-r--r--tools/perf/util/bpf-loader.h85
-rw-r--r--tools/perf/util/callchain.c42
-rw-r--r--tools/perf/util/callchain.h26
-rw-r--r--tools/perf/util/cpumap.c97
-rw-r--r--tools/perf/util/cpumap.h10
-rw-r--r--tools/perf/util/env.c86
-rw-r--r--tools/perf/util/env.h44
-rw-r--r--tools/perf/util/event.c22
-rw-r--r--tools/perf/util/event.h6
-rw-r--r--tools/perf/util/evlist.c185
-rw-r--r--tools/perf/util/evlist.h14
-rw-r--r--tools/perf/util/evsel.c51
-rw-r--r--tools/perf/util/evsel.h11
-rw-r--r--tools/perf/util/header.c140
-rw-r--r--tools/perf/util/header.h27
-rw-r--r--tools/perf/util/hist.c59
-rw-r--r--tools/perf/util/hist.h8
-rw-r--r--tools/perf/util/include/dwarf-regs.h8
-rw-r--r--tools/perf/util/intel-bts.c2
-rw-r--r--tools/perf/util/intel-pt-decoder/Build13
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c4
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-log.c21
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-log.h38
-rw-r--r--tools/perf/util/intel-pt-decoder/x86-opcode-map.txt24
-rw-r--r--tools/perf/util/intel-pt.c268
-rw-r--r--tools/perf/util/machine.c29
-rw-r--r--tools/perf/util/machine.h9
-rw-r--r--tools/perf/util/map.c21
-rw-r--r--tools/perf/util/map.h2
-rw-r--r--tools/perf/util/parse-branch-options.c1
-rw-r--r--tools/perf/util/parse-events.c381
-rw-r--r--tools/perf/util/parse-events.h16
-rw-r--r--tools/perf/util/parse-events.l12
-rw-r--r--tools/perf/util/parse-events.y84
-rw-r--r--tools/perf/util/parse-options.c156
-rw-r--r--tools/perf/util/parse-options.h5
-rw-r--r--tools/perf/util/perf_regs.c2
-rw-r--r--tools/perf/util/perf_regs.h1
-rw-r--r--tools/perf/util/pmu.c42
-rw-r--r--tools/perf/util/probe-event.c247
-rw-r--r--tools/perf/util/probe-event.h11
-rw-r--r--tools/perf/util/probe-file.c56
-rw-r--r--tools/perf/util/probe-file.h4
-rw-r--r--tools/perf/util/probe-finder.c58
-rw-r--r--tools/perf/util/python.c59
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c1
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c3
-rw-r--r--tools/perf/util/session.c42
-rw-r--r--tools/perf/util/session.h2
-rw-r--r--tools/perf/util/sort.c74
-rw-r--r--tools/perf/util/sort.h6
-rw-r--r--tools/perf/util/srcline.c29
-rw-r--r--tools/perf/util/stat.c29
-rw-r--r--tools/perf/util/stat.h3
-rw-r--r--tools/perf/util/strbuf.c22
-rw-r--r--tools/perf/util/strbuf.h2
-rw-r--r--tools/perf/util/symbol-elf.c37
-rw-r--r--tools/perf/util/symbol-minimal.c2
-rw-r--r--tools/perf/util/symbol.c31
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/trace-event-info.c2
-rw-r--r--tools/perf/util/trace-event.c16
-rw-r--r--tools/perf/util/trace-event.h2
-rw-r--r--tools/perf/util/unwind-libunwind.c19
-rw-r--r--tools/perf/util/usage.c5
-rw-r--r--tools/perf/util/util.c74
-rw-r--r--tools/perf/util/util.h12
157 files changed, 7581 insertions, 1593 deletions
diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt
index 4a0501d7a3b4..be764f9ec769 100644
--- a/tools/perf/Documentation/intel-pt.txt
+++ b/tools/perf/Documentation/intel-pt.txt
@@ -364,21 +364,6 @@ cyc_thresh Specifies how frequently CYC packets are produced - see cyc
364 364
365 CYC packets are not requested by default. 365 CYC packets are not requested by default.
366 366
367no_force_psb This is a driver option and is not in the IA32_RTIT_CTL MSR.
368
369 It stops the driver resetting the byte count to zero whenever
370 enabling the trace (for example on context switches) which in
371 turn results in no PSB being forced. However some processors
372 will produce a PSB anyway.
373
374 In any case, there is still a PSB when the trace is enabled for
375 the first time.
376
377 no_force_psb can be used to slightly decrease the trace size but
378 may make it harder for the decoder to recover from errors.
379
380 no_force_psb is not selected by default.
381
382 367
383new snapshot option 368new snapshot option
384------------------- 369-------------------
@@ -686,6 +671,7 @@ The letters are:
686 e synthesize tracing error events 671 e synthesize tracing error events
687 d create a debug log 672 d create a debug log
688 g synthesize a call chain (use with i or x) 673 g synthesize a call chain (use with i or x)
674 l synthesize last branch entries (use with i or x)
689 675
690"Instructions" events look like they were recorded by "perf record -e 676"Instructions" events look like they were recorded by "perf record -e
691instructions". 677instructions".
@@ -722,12 +708,26 @@ on the sample is *not* adjusted and reflects the last known value of TSC.
722 708
723For Intel PT, the default period is 100us. 709For Intel PT, the default period is 100us.
724 710
711Setting it to a zero period means "as often as possible".
712
713In the case of Intel PT that is the same as a period of 1 and a unit of
714'instructions' (i.e. --itrace=i1i).
715
725Also the call chain size (default 16, max. 1024) for instructions or 716Also the call chain size (default 16, max. 1024) for instructions or
726transactions events can be specified. e.g. 717transactions events can be specified. e.g.
727 718
728 --itrace=ig32 719 --itrace=ig32
729 --itrace=xg32 720 --itrace=xg32
730 721
722Also the number of last branch entries (default 64, max. 1024) for instructions or
723transactions events can be specified. e.g.
724
725 --itrace=il10
726 --itrace=xl10
727
728Note that last branch entries are cleared for each sample, so there is no overlap
729from one sample to the next.
730
731To disable trace decoding entirely, use the option --no-itrace. 731To disable trace decoding entirely, use the option --no-itrace.
732 732
733 733
@@ -764,3 +764,32 @@ perf inject also accepts the --itrace option in which case tracing data is
764removed and replaced with the synthesized events. e.g. 764removed and replaced with the synthesized events. e.g.
765 765
766 perf inject --itrace -i perf.data -o perf.data.new 766 perf inject --itrace -i perf.data -o perf.data.new
767
768Below is an example of using Intel PT with autofdo. It requires autofdo
769(https://github.com/google/autofdo) and gcc version 5. The bubble
770sort example is from the AutoFDO tutorial (https://gcc.gnu.org/wiki/AutoFDO/Tutorial)
771amended to take the number of elements as a parameter.
772
773 $ gcc-5 -O3 sort.c -o sort_optimized
774 $ ./sort_optimized 30000
775 Bubble sorting array of 30000 elements
776 2254 ms
777
778 $ cat ~/.perfconfig
779 [intel-pt]
780 mispred-all
781
782 $ perf record -e intel_pt//u ./sort 3000
783 Bubble sorting array of 3000 elements
784 58 ms
785 [ perf record: Woken up 2 times to write data ]
786 [ perf record: Captured and wrote 3.939 MB perf.data ]
787 $ perf inject -i perf.data -o inj --itrace=i100usle --strip
788 $ ./create_gcov --binary=./sort --profile=inj --gcov=sort.gcov -gcov_version=1
789 $ gcc-5 -O3 -fauto-profile=sort.gcov sort.c -o sort_autofdo
790 $ ./sort_autofdo 30000
791 Bubble sorting array of 30000 elements
792 2155 ms
793
794Note there is currently no advantage to using Intel PT instead of LBR, but
795that may change in the future if greater use is made of the data.
diff --git a/tools/perf/Documentation/itrace.txt b/tools/perf/Documentation/itrace.txt
index 2ff946677e3b..65453f4c7006 100644
--- a/tools/perf/Documentation/itrace.txt
+++ b/tools/perf/Documentation/itrace.txt
@@ -6,6 +6,7 @@
6 e synthesize error events 6 e synthesize error events
7 d create a debug log 7 d create a debug log
8 g synthesize a call chain (use with i or x) 8 g synthesize a call chain (use with i or x)
9 l synthesize last branch entries (use with i or x)
9 10
10 The default is all events i.e. the same as --itrace=ibxe 11 The default is all events i.e. the same as --itrace=ibxe
11 12
@@ -20,3 +21,6 @@
20 21
21 Also the call chain size (default 16, max. 1024) for instructions or 22 Also the call chain size (default 16, max. 1024) for instructions or
22 transactions events can be specified. 23 transactions events can be specified.
24
25 Also the number of last branch entries (default 64, max. 1024) for
26 instructions or transactions events can be specified.
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
index ab632d9fbd7d..34750fc32714 100644
--- a/tools/perf/Documentation/perf-bench.txt
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -82,7 +82,7 @@ Be multi thread instead of multi process
82Specify number of groups 82Specify number of groups
83 83
84-l:: 84-l::
85--loop=:: 85--nr_loops=::
86Specify number of loops 86Specify number of loops
87 87
88Example of *messaging* 88Example of *messaging*
@@ -139,64 +139,48 @@ Suite for evaluating performance of simple memory copy in various ways.
139Options of *memcpy* 139Options of *memcpy*
140^^^^^^^^^^^^^^^^^^^ 140^^^^^^^^^^^^^^^^^^^
141-l:: 141-l::
142--length:: 142--size::
143Specify length of memory to copy (default: 1MB). 143Specify size of memory to copy (default: 1MB).
144Available units are B, KB, MB, GB and TB (case insensitive). 144Available units are B, KB, MB, GB and TB (case insensitive).
145 145
146-r:: 146-f::
147--routine:: 147--function::
148Specify routine to copy (default: default). 148Specify function to copy (default: default).
149Available routines are depend on the architecture. 149Available functions are depend on the architecture.
150On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. 150On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported.
151 151
152-i:: 152-l::
153--iterations:: 153--nr_loops::
154Repeat memcpy invocation this number of times. 154Repeat memcpy invocation this number of times.
155 155
156-c:: 156-c::
157--cycle:: 157--cycles::
158Use perf's cpu-cycles event instead of gettimeofday syscall. 158Use perf's cpu-cycles event instead of gettimeofday syscall.
159 159
160-o::
161--only-prefault::
162Show only the result with page faults before memcpy.
163
164-n::
165--no-prefault::
166Show only the result without page faults before memcpy.
167
168*memset*:: 160*memset*::
169Suite for evaluating performance of simple memory set in various ways. 161Suite for evaluating performance of simple memory set in various ways.
170 162
171Options of *memset* 163Options of *memset*
172^^^^^^^^^^^^^^^^^^^ 164^^^^^^^^^^^^^^^^^^^
173-l:: 165-l::
174--length:: 166--size::
175Specify length of memory to set (default: 1MB). 167Specify size of memory to set (default: 1MB).
176Available units are B, KB, MB, GB and TB (case insensitive). 168Available units are B, KB, MB, GB and TB (case insensitive).
177 169
178-r:: 170-f::
179--routine:: 171--function::
180Specify routine to set (default: default). 172Specify function to set (default: default).
181Available routines are depend on the architecture. 173Available functions are depend on the architecture.
182On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. 174On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported.
183 175
184-i:: 176-l::
185--iterations:: 177--nr_loops::
186Repeat memset invocation this number of times. 178Repeat memset invocation this number of times.
187 179
188-c:: 180-c::
189--cycle:: 181--cycles::
190Use perf's cpu-cycles event instead of gettimeofday syscall. 182Use perf's cpu-cycles event instead of gettimeofday syscall.
191 183
192-o::
193--only-prefault::
194Show only the result with page faults before memset.
195
196-n::
197--no-prefault::
198Show only the result without page faults before memset.
199
200SUITES FOR 'numa' 184SUITES FOR 'numa'
201~~~~~~~~~~~~~~~~~ 185~~~~~~~~~~~~~~~~~
202*mem*:: 186*mem*::
diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt
index 0c721c3e37e1..0b1cedeef895 100644
--- a/tools/perf/Documentation/perf-inject.txt
+++ b/tools/perf/Documentation/perf-inject.txt
@@ -50,6 +50,9 @@ OPTIONS
50 50
51include::itrace.txt[] 51include::itrace.txt[]
52 52
53--strip::
54 Use with --itrace to strip out non-synthesized events.
55
53SEE ALSO 56SEE ALSO
54-------- 57--------
55linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1] 58linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1]
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index bada8933fdd4..79483f40e991 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -30,6 +30,7 @@ counted. The following modifiers exist:
30 G - guest counting (in KVM guests) 30 G - guest counting (in KVM guests)
31 H - host counting (not in KVM guests) 31 H - host counting (not in KVM guests)
32 p - precise level 32 p - precise level
33 P - use maximum detected precise level
33 S - read sample value (PERF_SAMPLE_READ) 34 S - read sample value (PERF_SAMPLE_READ)
34 D - pin the event to the PMU 35 D - pin the event to the PMU
35 36
@@ -125,6 +126,8 @@ To limit the list use:
125. If none of the above is matched, it will apply the supplied glob to all 126. If none of the above is matched, it will apply the supplied glob to all
126 events, printing the ones that match. 127 events, printing the ones that match.
127 128
129. As a last resort, it will do a substring search in all event names.
130
128One or more types can be used at the same time, listing the events for the 131One or more types can be used at the same time, listing the events for the
129types specified. 132types specified.
130 133
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 2e9ce77b5e14..e630a7d2c348 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -144,7 +144,7 @@ OPTIONS
144 144
145--call-graph:: 145--call-graph::
146 Setup and enable call-graph (stack chain/backtrace) recording, 146 Setup and enable call-graph (stack chain/backtrace) recording,
147 implies -g. 147 implies -g. Default is "fp".
148 148
149 Allows specifying "fp" (frame pointer) or "dwarf" 149 Allows specifying "fp" (frame pointer) or "dwarf"
150 (DWARF's CFI - Call Frame Information) or "lbr" 150 (DWARF's CFI - Call Frame Information) or "lbr"
@@ -154,13 +154,18 @@ OPTIONS
154 In some systems, where binaries are build with gcc 154 In some systems, where binaries are build with gcc
155 --fomit-frame-pointer, using the "fp" method will produce bogus 155 --fomit-frame-pointer, using the "fp" method will produce bogus
156 call graphs, using "dwarf", if available (perf tools linked to 156 call graphs, using "dwarf", if available (perf tools linked to
157 the libunwind library) should be used instead. 157 the libunwind or libdw library) should be used instead.
158 Using the "lbr" method doesn't require any compiler options. It 158 Using the "lbr" method doesn't require any compiler options. It
159 will produce call graphs from the hardware LBR registers. The 159 will produce call graphs from the hardware LBR registers. The
160 main limition is that it is only available on new Intel 160 main limition is that it is only available on new Intel
161 platforms, such as Haswell. It can only get user call chain. It 161 platforms, such as Haswell. It can only get user call chain. It
162 doesn't work with branch stack sampling at the same time. 162 doesn't work with branch stack sampling at the same time.
163 163
164 When "dwarf" recording is used, perf also records (user) stack dump
165 when sampled. Default size of the stack dump is 8192 (bytes).
166 User can change the size by passing the size after comma like
167 "--call-graph dwarf,4096".
168
164-q:: 169-q::
165--quiet:: 170--quiet::
166 Don't print any message, useful for scripting. 171 Don't print any message, useful for scripting.
@@ -236,6 +241,7 @@ following filters are defined:
236 - any_call: any function call or system call 241 - any_call: any function call or system call
237 - any_ret: any function return or system call return 242 - any_ret: any function return or system call return
238 - ind_call: any indirect branch 243 - ind_call: any indirect branch
244 - call: direct calls, including far (to/from kernel) calls
239 - u: only when the branch target is at the user level 245 - u: only when the branch target is at the user level
240 - k: only when the branch target is in the kernel 246 - k: only when the branch target is in the kernel
241 - hv: only when the target is at the hypervisor level 247 - hv: only when the target is at the hypervisor level
@@ -308,6 +314,12 @@ This option sets the time out limit. The default value is 500 ms.
308Record context switch events i.e. events of type PERF_RECORD_SWITCH or 314Record context switch events i.e. events of type PERF_RECORD_SWITCH or
309PERF_RECORD_SWITCH_CPU_WIDE. 315PERF_RECORD_SWITCH_CPU_WIDE.
310 316
317--clang-path::
318Path to clang binary to use for compiling BPF scriptlets.
319
320--clang-opt::
321Options passed to clang when compiling BPF scriptlets.
322
311SEE ALSO 323SEE ALSO
312-------- 324--------
313linkperf:perf-stat[1], linkperf:perf-list[1] 325linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 9c7981bfddad..5ce8da1e1256 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -29,7 +29,7 @@ OPTIONS
29--show-nr-samples:: 29--show-nr-samples::
30 Show the number of samples for each symbol 30 Show the number of samples for each symbol
31 31
32--showcpuutilization:: 32--show-cpu-utilization::
33 Show sample percentage for different cpu modes. 33 Show sample percentage for different cpu modes.
34 34
35-T:: 35-T::
@@ -68,7 +68,7 @@ OPTIONS
68--sort=:: 68--sort=::
69 Sort histogram entries by given key(s) - multiple keys can be specified 69 Sort histogram entries by given key(s) - multiple keys can be specified
70 in CSV format. Following sort keys are available: 70 in CSV format. Following sort keys are available:
71 pid, comm, dso, symbol, parent, cpu, srcline, weight, local_weight. 71 pid, comm, dso, symbol, parent, cpu, socket, srcline, weight, local_weight.
72 72
73 Each key has following meaning: 73 Each key has following meaning:
74 74
@@ -79,6 +79,7 @@ OPTIONS
79 - parent: name of function matched to the parent regex filter. Unmatched 79 - parent: name of function matched to the parent regex filter. Unmatched
80 entries are displayed as "[other]". 80 entries are displayed as "[other]".
81 - cpu: cpu number the task ran at the time of sample 81 - cpu: cpu number the task ran at the time of sample
82 - socket: processor socket number the task ran at the time of sample
82 - srcline: filename and line number executed at the time of sample. The 83 - srcline: filename and line number executed at the time of sample. The
83 DWARF debugging info must be provided. 84 DWARF debugging info must be provided.
84 - srcfile: file name of the source file of the same. Requires dwarf 85 - srcfile: file name of the source file of the same. Requires dwarf
@@ -168,30 +169,40 @@ OPTIONS
168--dump-raw-trace:: 169--dump-raw-trace::
169 Dump raw trace in ASCII. 170 Dump raw trace in ASCII.
170 171
171-g [type,min[,limit],order[,key][,branch]]:: 172-g::
172--call-graph:: 173--call-graph=<print_type,threshold[,print_limit],order,sort_key,branch>::
173 Display call chains using type, min percent threshold, optional print 174 Display call chains using type, min percent threshold, print limit,
174 limit and order. 175 call order, sort key and branch. Note that ordering of parameters is not
175 type can be either: 176 fixed so any parement can be given in an arbitraty order. One exception
177 is the print_limit which should be preceded by threshold.
178
179 print_type can be either:
176 - flat: single column, linear exposure of call chains. 180 - flat: single column, linear exposure of call chains.
177 - graph: use a graph tree, displaying absolute overhead rates. 181 - graph: use a graph tree, displaying absolute overhead rates. (default)
178 - fractal: like graph, but displays relative rates. Each branch of 182 - fractal: like graph, but displays relative rates. Each branch of
179 the tree is considered as a new profiled object. + 183 the tree is considered as a new profiled object.
184 - none: disable call chain display.
185
186 threshold is a percentage value which specifies a minimum percent to be
187 included in the output call graph. Default is 0.5 (%).
188
189 print_limit is only applied when stdio interface is used. It's to limit
190 number of call graph entries in a single hist entry. Note that it needs
191 to be given after threshold (but not necessarily consecutive).
192 Default is 0 (unlimited).
180 193
181 order can be either: 194 order can be either:
182 - callee: callee based call graph. 195 - callee: callee based call graph.
183 - caller: inverted caller based call graph. 196 - caller: inverted caller based call graph.
197 Default is 'caller' when --children is used, otherwise 'callee'.
184 198
185 key can be: 199 sort_key can be:
186 - function: compare on functions 200 - function: compare on functions (default)
187 - address: compare on individual code addresses 201 - address: compare on individual code addresses
188 202
189 branch can be: 203 branch can be:
190 - branch: include last branch information in callgraph 204 - branch: include last branch information in callgraph when available.
191 when available. Usually more convenient to use --branch-history 205 Usually more convenient to use --branch-history for this.
192 for this.
193
194 Default: fractal,0.5,callee,function.
195 206
196--children:: 207--children::
197 Accumulate callchain of children to parent entry so that then can 208 Accumulate callchain of children to parent entry so that then can
@@ -204,6 +215,8 @@ OPTIONS
204 beyond the specified depth will be ignored. This is a trade-off 215 beyond the specified depth will be ignored. This is a trade-off
205 between information loss and faster processing especially for 216 between information loss and faster processing especially for
206 workloads that can have a very long callchain stack. 217 workloads that can have a very long callchain stack.
218 Note that when using the --itrace option the synthesized callchain size
219 will override this value if the synthesized callchain size is bigger.
207 220
208 Default: 127 221 Default: 127
209 222
@@ -349,6 +362,9 @@ include::itrace.txt[]
349 This option extends the perf report to show reference callgraphs, 362 This option extends the perf report to show reference callgraphs,
350 which collected by reference event, in no callgraph event. 363 which collected by reference event, in no callgraph event.
351 364
365--socket-filter::
366 Only report the samples on the processor socket that match with this filter
367
352include::callchain-overhead-calculation.txt[] 368include::callchain-overhead-calculation.txt[]
353 369
354SEE ALSO 370SEE ALSO
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index dc3ec783b7bd..382ddfb45d1d 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -112,11 +112,11 @@ OPTIONS
112--debug-mode:: 112--debug-mode::
113 Do various checks like samples ordering and lost events. 113 Do various checks like samples ordering and lost events.
114 114
115-f:: 115-F::
116--fields:: 116--fields::
117 Comma separated list of fields to print. Options are: 117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, 118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
119 srcline, period, iregs, 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
@@ -175,6 +175,16 @@ OPTIONS
175 Finally, a user may not set fields to none for all event types. 175 Finally, a user may not set fields to none for all event types.
176 i.e., -f "" is not allowed. 176 i.e., -f "" is not allowed.
177 177
178 The brstack output includes branch related information with raw addresses using the
179 /v/v/v/v/ syntax in the following order:
180 FROM: branch source instruction
181 TO : branch target instruction
182 M/P/-: M=branch target mispredicted or branch direction was mispredicted, P=target predicted or direction predicted, -=not supported
183 X/- : X=branch inside a transactional region, -=not in transaction region or not supported
184 A/- : A=TSX abort entry, -=not aborted region or not supported
185
186 The brstacksym is identical to brstack, except that the FROM and TO addresses are printed in a symbolic form if possible.
187
178-k:: 188-k::
179--vmlinux=<file>:: 189--vmlinux=<file>::
180 vmlinux pathname 190 vmlinux pathname
@@ -249,6 +259,9 @@ include::itrace.txt[]
249--full-source-path:: 259--full-source-path::
250 Show the full path for source files for srcline output. 260 Show the full path for source files for srcline output.
251 261
262--ns::
263 Use 9 decimal places when displaying time (i.e. show the nanoseconds)
264
252SEE ALSO 265SEE ALSO
253-------- 266--------
254linkperf:perf-record[1], linkperf:perf-script-perl[1], 267linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 47469abdcc1c..4e074a660826 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -128,8 +128,9 @@ perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' -- m
128 128
129-I msecs:: 129-I msecs::
130--interval-print msecs:: 130--interval-print msecs::
131 Print count deltas every N milliseconds (minimum: 100ms) 131Print count deltas every N milliseconds (minimum: 10ms)
132 example: perf stat -I 1000 -e cycles -a sleep 5 132The overhead percentage could be high in some cases, for instance with small, sub 100ms intervals. Use with caution.
133 example: 'perf stat -I 1000 -e cycles -a sleep 5'
133 134
134--per-socket:: 135--per-socket::
135Aggregate counts per processor socket for system-wide mode measurements. This 136Aggregate counts per processor socket for system-wide mode measurements. This
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index f6a23eb294e7..556cec09bf50 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -160,9 +160,10 @@ Default is to monitor all CPUS.
160-g:: 160-g::
161 Enables call-graph (stack chain/backtrace) recording. 161 Enables call-graph (stack chain/backtrace) recording.
162 162
163--call-graph:: 163--call-graph [mode,type,min[,limit],order[,key][,branch]]::
164 Setup and enable call-graph (stack chain/backtrace) recording, 164 Setup and enable call-graph (stack chain/backtrace) recording,
165 implies -g. 165 implies -g. See `--call-graph` section in perf-record and
166 perf-report man pages for details.
166 167
167--children:: 168--children::
168 Accumulate callchain of children to parent entry so that then can 169 Accumulate callchain of children to parent entry so that then can
diff --git a/tools/perf/Documentation/perf.txt b/tools/perf/Documentation/perf.txt
index 2b131776363e..864e37597252 100644
--- a/tools/perf/Documentation/perf.txt
+++ b/tools/perf/Documentation/perf.txt
@@ -27,6 +27,14 @@ OPTIONS
27 Setup buildid cache directory. It has higher priority than 27 Setup buildid cache directory. It has higher priority than
28 buildid.dir config file option. 28 buildid.dir config file option.
29 29
30-v::
31--version::
32 Display perf version.
33
34-h::
35--help::
36 Run perf help command.
37
30DESCRIPTION 38DESCRIPTION
31----------- 39-----------
32Performance counters for Linux are a new kernel-based subsystem 40Performance counters for Linux are a new kernel-based subsystem
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index af009bd6e6b7..39c38cb45b00 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -17,6 +17,7 @@ tools/build
17tools/arch/x86/include/asm/atomic.h 17tools/arch/x86/include/asm/atomic.h
18tools/arch/x86/include/asm/rmwcc.h 18tools/arch/x86/include/asm/rmwcc.h
19tools/lib/traceevent 19tools/lib/traceevent
20tools/lib/bpf
20tools/lib/api 21tools/lib/api
21tools/lib/bpf 22tools/lib/bpf
22tools/lib/hweight.c 23tools/lib/hweight.c
@@ -41,6 +42,7 @@ tools/include/asm-generic/bitops.h
41tools/include/linux/atomic.h 42tools/include/linux/atomic.h
42tools/include/linux/bitops.h 43tools/include/linux/bitops.h
43tools/include/linux/compiler.h 44tools/include/linux/compiler.h
45tools/include/linux/filter.h
44tools/include/linux/hash.h 46tools/include/linux/hash.h
45tools/include/linux/kernel.h 47tools/include/linux/kernel.h
46tools/include/linux/list.h 48tools/include/linux/list.h
@@ -49,6 +51,7 @@ tools/include/linux/poison.h
49tools/include/linux/rbtree.h 51tools/include/linux/rbtree.h
50tools/include/linux/rbtree_augmented.h 52tools/include/linux/rbtree_augmented.h
51tools/include/linux/types.h 53tools/include/linux/types.h
54tools/include/linux/err.h
52include/asm-generic/bitops/arch_hweight.h 55include/asm-generic/bitops/arch_hweight.h
53include/asm-generic/bitops/const_hweight.h 56include/asm-generic/bitops/const_hweight.h
54include/asm-generic/bitops/fls64.h 57include/asm-generic/bitops/fls64.h
@@ -67,6 +70,8 @@ arch/*/lib/memset*.S
67include/linux/poison.h 70include/linux/poison.h
68include/linux/hw_breakpoint.h 71include/linux/hw_breakpoint.h
69include/uapi/linux/perf_event.h 72include/uapi/linux/perf_event.h
73include/uapi/linux/bpf.h
74include/uapi/linux/bpf_common.h
70include/uapi/linux/const.h 75include/uapi/linux/const.h
71include/uapi/linux/swab.h 76include/uapi/linux/swab.h
72include/uapi/linux/hw_breakpoint.h 77include/uapi/linux/hw_breakpoint.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index d9863cb96f59..0d19d5447d6c 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -75,6 +75,8 @@ include config/utilities.mak
75# Define NO_LZMA if you do not want to support compressed (xz) kernel modules 75# Define NO_LZMA if you do not want to support compressed (xz) kernel modules
76# 76#
77# Define NO_AUXTRACE if you do not want AUX area tracing support 77# Define NO_AUXTRACE if you do not want AUX area tracing support
78#
79# Define NO_LIBBPF if you do not want BPF support
78 80
79# As per kernel Makefile, avoid funny character set dependencies 81# As per kernel Makefile, avoid funny character set dependencies
80unexport LC_ALL 82unexport LC_ALL
@@ -145,6 +147,7 @@ AWK = awk
145 147
146LIB_DIR = $(srctree)/tools/lib/api/ 148LIB_DIR = $(srctree)/tools/lib/api/
147TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ 149TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
150BPF_DIR = $(srctree)/tools/lib/bpf/
148 151
149# include config/Makefile by default and rule out 152# include config/Makefile by default and rule out
150# non-config cases 153# non-config cases
@@ -180,6 +183,7 @@ strip-libs = $(filter-out -l%,$(1))
180 183
181ifneq ($(OUTPUT),) 184ifneq ($(OUTPUT),)
182 TE_PATH=$(OUTPUT) 185 TE_PATH=$(OUTPUT)
186 BPF_PATH=$(OUTPUT)
183ifneq ($(subdir),) 187ifneq ($(subdir),)
184 LIB_PATH=$(OUTPUT)/../lib/api/ 188 LIB_PATH=$(OUTPUT)/../lib/api/
185else 189else
@@ -188,6 +192,7 @@ endif
188else 192else
189 TE_PATH=$(TRACE_EVENT_DIR) 193 TE_PATH=$(TRACE_EVENT_DIR)
190 LIB_PATH=$(LIB_DIR) 194 LIB_PATH=$(LIB_DIR)
195 BPF_PATH=$(BPF_DIR)
191endif 196endif
192 197
193LIBTRACEEVENT = $(TE_PATH)libtraceevent.a 198LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
@@ -199,6 +204,8 @@ LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYN
199LIBAPI = $(LIB_PATH)libapi.a 204LIBAPI = $(LIB_PATH)libapi.a
200export LIBAPI 205export LIBAPI
201 206
207LIBBPF = $(BPF_PATH)libbpf.a
208
202# python extension build directories 209# python extension build directories
203PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ 210PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/
204PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/ 211PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/
@@ -251,6 +258,9 @@ export PERL_PATH
251LIB_FILE=$(OUTPUT)libperf.a 258LIB_FILE=$(OUTPUT)libperf.a
252 259
253PERFLIBS = $(LIB_FILE) $(LIBAPI) $(LIBTRACEEVENT) 260PERFLIBS = $(LIB_FILE) $(LIBAPI) $(LIBTRACEEVENT)
261ifndef NO_LIBBPF
262 PERFLIBS += $(LIBBPF)
263endif
254 264
255# We choose to avoid "if .. else if .. else .. endif endif" 265# We choose to avoid "if .. else if .. else .. endif endif"
256# because maintaining the nesting to match is a pain. If 266# because maintaining the nesting to match is a pain. If
@@ -297,16 +307,16 @@ strip: $(PROGRAMS) $(OUTPUT)perf
297PERF_IN := $(OUTPUT)perf-in.o 307PERF_IN := $(OUTPUT)perf-in.o
298 308
299export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK 309export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK
300build := -f $(srctree)/tools/build/Makefile.build dir=. obj 310include $(srctree)/tools/build/Makefile.include
301 311
302$(PERF_IN): $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h FORCE 312$(PERF_IN): prepare FORCE
303 $(Q)$(MAKE) $(build)=perf 313 $(Q)$(MAKE) $(build)=perf
304 314
305$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) 315$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
306 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \ 316 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \
307 $(PERF_IN) $(LIBS) -o $@ 317 $(PERF_IN) $(LIBS) -o $@
308 318
309$(GTK_IN): FORCE 319$(GTK_IN): fixdep FORCE
310 $(Q)$(MAKE) $(build)=gtk 320 $(Q)$(MAKE) $(build)=gtk
311 321
312$(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS) 322$(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS)
@@ -349,27 +359,27 @@ endif
349__build-dir = $(subst $(OUTPUT),,$(dir $@)) 359__build-dir = $(subst $(OUTPUT),,$(dir $@))
350build-dir = $(if $(__build-dir),$(__build-dir),.) 360build-dir = $(if $(__build-dir),$(__build-dir),.)
351 361
352single_dep: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h 362prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep
353 363
354$(OUTPUT)%.o: %.c single_dep FORCE 364$(OUTPUT)%.o: %.c prepare FORCE
355 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 365 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
356 366
357$(OUTPUT)%.i: %.c single_dep FORCE 367$(OUTPUT)%.i: %.c prepare FORCE
358 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 368 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
359 369
360$(OUTPUT)%.s: %.c single_dep FORCE 370$(OUTPUT)%.s: %.c prepare FORCE
361 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 371 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
362 372
363$(OUTPUT)%-bison.o: %.c single_dep FORCE 373$(OUTPUT)%-bison.o: %.c prepare FORCE
364 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 374 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
365 375
366$(OUTPUT)%-flex.o: %.c single_dep FORCE 376$(OUTPUT)%-flex.o: %.c prepare FORCE
367 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 377 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
368 378
369$(OUTPUT)%.o: %.S single_dep FORCE 379$(OUTPUT)%.o: %.S prepare FORCE
370 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 380 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
371 381
372$(OUTPUT)%.i: %.S single_dep FORCE 382$(OUTPUT)%.i: %.S prepare FORCE
373 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ 383 $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
374 384
375$(OUTPUT)perf-%: %.o $(PERFLIBS) 385$(OUTPUT)perf-%: %.o $(PERFLIBS)
@@ -389,7 +399,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h)
389 399
390LIBPERF_IN := $(OUTPUT)libperf-in.o 400LIBPERF_IN := $(OUTPUT)libperf-in.o
391 401
392$(LIBPERF_IN): FORCE 402$(LIBPERF_IN): fixdep FORCE
393 $(Q)$(MAKE) $(build)=libperf 403 $(Q)$(MAKE) $(build)=libperf
394 404
395$(LIB_FILE): $(LIBPERF_IN) 405$(LIB_FILE): $(LIBPERF_IN)
@@ -397,10 +407,10 @@ $(LIB_FILE): $(LIBPERF_IN)
397 407
398LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 408LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ)
399 409
400$(LIBTRACEEVENT): FORCE 410$(LIBTRACEEVENT): fixdep FORCE
401 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a 411 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a
402 412
403libtraceevent_plugins: FORCE 413libtraceevent_plugins: fixdep FORCE
404 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins 414 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins
405 415
406$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins 416$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins
@@ -413,13 +423,20 @@ $(LIBTRACEEVENT)-clean:
413install-traceevent-plugins: $(LIBTRACEEVENT) 423install-traceevent-plugins: $(LIBTRACEEVENT)
414 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins 424 $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins
415 425
416$(LIBAPI): FORCE 426$(LIBAPI): fixdep FORCE
417 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a 427 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a
418 428
419$(LIBAPI)-clean: 429$(LIBAPI)-clean:
420 $(call QUIET_CLEAN, libapi) 430 $(call QUIET_CLEAN, libapi)
421 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null 431 $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null
422 432
433$(LIBBPF): fixdep FORCE
434 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) $(OUTPUT)libbpf.a
435
436$(LIBBPF)-clean:
437 $(call QUIET_CLEAN, libbpf)
438 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null
439
423help: 440help:
424 @echo 'Perf make targets:' 441 @echo 'Perf make targets:'
425 @echo ' doc - make *all* documentation (see below)' 442 @echo ' doc - make *all* documentation (see below)'
@@ -459,7 +476,7 @@ INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
459$(DOC_TARGETS): 476$(DOC_TARGETS):
460 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all) 477 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
461 478
462TAG_FOLDERS= . ../lib/traceevent ../lib/api ../lib/symbol 479TAG_FOLDERS= . ../lib/traceevent ../lib/api ../lib/symbol ../include ../lib/bpf
463TAG_FILES= ../../include/uapi/linux/perf_event.h 480TAG_FILES= ../../include/uapi/linux/perf_event.h
464 481
465TAGS: 482TAGS:
@@ -567,7 +584,7 @@ config-clean:
567 $(call QUIET_CLEAN, config) 584 $(call QUIET_CLEAN, config)
568 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null 585 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null
569 586
570clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean 587clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean config-clean
571 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) 588 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
572 $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete 589 $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
573 $(Q)$(RM) $(OUTPUT).config-detected 590 $(Q)$(RM) $(OUTPUT).config-detected
@@ -591,6 +608,6 @@ FORCE:
591 608
592.PHONY: all install clean config-clean strip install-gtk 609.PHONY: all install clean config-clean strip install-gtk
593.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 610.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
594.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE single_dep 611.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
595.PHONY: libtraceevent_plugins 612.PHONY: libtraceevent_plugins
596 613
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index b00dfd92ea73..e83c8ce24303 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -128,9 +128,8 @@ static const char *normalize_arch(char *arch)
128 return arch; 128 return arch;
129} 129}
130 130
131static int perf_session_env__lookup_binutils_path(struct perf_env *env, 131static int perf_env__lookup_binutils_path(struct perf_env *env,
132 const char *name, 132 const char *name, const char **path)
133 const char **path)
134{ 133{
135 int idx; 134 int idx;
136 const char *arch, *cross_env; 135 const char *arch, *cross_env;
@@ -206,7 +205,7 @@ out_error:
206 return -1; 205 return -1;
207} 206}
208 207
209int perf_session_env__lookup_objdump(struct perf_env *env) 208int perf_env__lookup_objdump(struct perf_env *env)
210{ 209{
211 /* 210 /*
212 * For live mode, env->arch will be NULL and we can use 211 * For live mode, env->arch will be NULL and we can use
@@ -215,6 +214,5 @@ int perf_session_env__lookup_objdump(struct perf_env *env)
215 if (env->arch == NULL) 214 if (env->arch == NULL)
216 return 0; 215 return 0;
217 216
218 return perf_session_env__lookup_binutils_path(env, "objdump", 217 return perf_env__lookup_binutils_path(env, "objdump", &objdump_path);
219 &objdump_path);
220} 218}
diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h
index 20176df69fc8..7529cfb143ce 100644
--- a/tools/perf/arch/common.h
+++ b/tools/perf/arch/common.h
@@ -1,10 +1,10 @@
1#ifndef ARCH_PERF_COMMON_H 1#ifndef ARCH_PERF_COMMON_H
2#define ARCH_PERF_COMMON_H 2#define ARCH_PERF_COMMON_H
3 3
4#include "../util/session.h" 4#include "../util/env.h"
5 5
6extern const char *objdump_path; 6extern const char *objdump_path;
7 7
8int perf_session_env__lookup_objdump(struct perf_env *env); 8int perf_env__lookup_objdump(struct perf_env *env);
9 9
10#endif /* ARCH_PERF_COMMON_H */ 10#endif /* ARCH_PERF_COMMON_H */
diff --git a/tools/perf/arch/x86/Build b/tools/perf/arch/x86/Build
index 41bf61da476a..db52fa22d3a1 100644
--- a/tools/perf/arch/x86/Build
+++ b/tools/perf/arch/x86/Build
@@ -1,2 +1,2 @@
1libperf-y += util/ 1libperf-y += util/
2libperf-$(CONFIG_DWARF_UNWIND) += tests/ 2libperf-y += tests/
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 21322e0385b8..09ba923debe8 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -2,3 +2,4 @@ ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1 2PERF_HAVE_DWARF_REGS := 1
3endif 3endif
4HAVE_KVM_STAT_SUPPORT := 1 4HAVE_KVM_STAT_SUPPORT := 1
5PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
diff --git a/tools/perf/arch/x86/include/arch-tests.h b/tools/perf/arch/x86/include/arch-tests.h
new file mode 100644
index 000000000000..7ed00f4b0908
--- /dev/null
+++ b/tools/perf/arch/x86/include/arch-tests.h
@@ -0,0 +1,19 @@
1#ifndef ARCH_TESTS_H
2#define ARCH_TESTS_H
3
4/* Tests */
5int test__rdpmc(void);
6int test__perf_time_to_tsc(void);
7int test__insn_x86(void);
8int test__intel_cqm_count_nmi_context(void);
9
10#ifdef HAVE_DWARF_UNWIND_SUPPORT
11struct thread;
12struct perf_sample;
13int test__arch_unwind_sample(struct perf_sample *sample,
14 struct thread *thread);
15#endif
16
17extern struct test arch_tests[];
18
19#endif
diff --git a/tools/perf/arch/x86/tests/Build b/tools/perf/arch/x86/tests/Build
index b30eff9bcc83..cbb7e978166b 100644
--- a/tools/perf/arch/x86/tests/Build
+++ b/tools/perf/arch/x86/tests/Build
@@ -1,2 +1,8 @@
1libperf-y += regs_load.o 1libperf-$(CONFIG_DWARF_UNWIND) += regs_load.o
2libperf-y += dwarf-unwind.o 2libperf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
3
4libperf-y += arch-tests.o
5libperf-y += rdpmc.o
6libperf-y += perf-time-to-tsc.o
7libperf-$(CONFIG_AUXTRACE) += insn-x86.o
8libperf-y += intel-cqm.o
diff --git a/tools/perf/arch/x86/tests/arch-tests.c b/tools/perf/arch/x86/tests/arch-tests.c
new file mode 100644
index 000000000000..2218cb64f840
--- /dev/null
+++ b/tools/perf/arch/x86/tests/arch-tests.c
@@ -0,0 +1,34 @@
1#include <string.h>
2#include "tests/tests.h"
3#include "arch-tests.h"
4
5struct test arch_tests[] = {
6 {
7 .desc = "x86 rdpmc test",
8 .func = test__rdpmc,
9 },
10 {
11 .desc = "Test converting perf time to TSC",
12 .func = test__perf_time_to_tsc,
13 },
14#ifdef HAVE_DWARF_UNWIND_SUPPORT
15 {
16 .desc = "Test dwarf unwind",
17 .func = test__dwarf_unwind,
18 },
19#endif
20#ifdef HAVE_AUXTRACE_SUPPORT
21 {
22 .desc = "Test x86 instruction decoder - new instructions",
23 .func = test__insn_x86,
24 },
25#endif
26 {
27 .desc = "Test intel cqm nmi context read",
28 .func = test__intel_cqm_count_nmi_context,
29 },
30 {
31 .func = NULL,
32 },
33
34};
diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c
index d8bbf7ad1681..7f209ce827bf 100644
--- a/tools/perf/arch/x86/tests/dwarf-unwind.c
+++ b/tools/perf/arch/x86/tests/dwarf-unwind.c
@@ -5,6 +5,7 @@
5#include "event.h" 5#include "event.h"
6#include "debug.h" 6#include "debug.h"
7#include "tests/tests.h" 7#include "tests/tests.h"
8#include "arch-tests.h"
8 9
9#define STACK_SIZE 8192 10#define STACK_SIZE 8192
10 11
diff --git a/tools/perf/arch/x86/tests/gen-insn-x86-dat.awk b/tools/perf/arch/x86/tests/gen-insn-x86-dat.awk
new file mode 100644
index 000000000000..a21454835cd4
--- /dev/null
+++ b/tools/perf/arch/x86/tests/gen-insn-x86-dat.awk
@@ -0,0 +1,75 @@
1#!/bin/awk -f
2# gen-insn-x86-dat.awk: script to convert data for the insn-x86 test
3# Copyright (c) 2015, 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
14BEGIN {
15 print "/*"
16 print " * Generated by gen-insn-x86-dat.sh and gen-insn-x86-dat.awk"
17 print " * from insn-x86-dat-src.c for inclusion by insn-x86.c"
18 print " * Do not change this code."
19 print "*/\n"
20 op = ""
21 branch = ""
22 rel = 0
23 going = 0
24}
25
26/ Start here / {
27 going = 1
28}
29
30/ Stop here / {
31 going = 0
32}
33
34/^\s*[0-9a-fA-F]+\:/ {
35 if (going) {
36 colon_pos = index($0, ":")
37 useful_line = substr($0, colon_pos + 1)
38 first_pos = match(useful_line, "[0-9a-fA-F]")
39 useful_line = substr(useful_line, first_pos)
40 gsub("\t", "\\t", useful_line)
41 printf "{{"
42 len = 0
43 for (i = 2; i <= NF; i++) {
44 if (match($i, "^[0-9a-fA-F][0-9a-fA-F]$")) {
45 printf "0x%s, ", $i
46 len += 1
47 } else {
48 break
49 }
50 }
51 printf "}, %d, %s, \"%s\", \"%s\",", len, rel, op, branch
52 printf "\n\"%s\",},\n", useful_line
53 op = ""
54 branch = ""
55 rel = 0
56 }
57}
58
59/ Expecting: / {
60 expecting_str = " Expecting: "
61 expecting_len = length(expecting_str)
62 expecting_pos = index($0, expecting_str)
63 useful_line = substr($0, expecting_pos + expecting_len)
64 for (i = 1; i <= NF; i++) {
65 if ($i == "Expecting:") {
66 i++
67 op = $i
68 i++
69 branch = $i
70 i++
71 rel = $i
72 break
73 }
74 }
75}
diff --git a/tools/perf/arch/x86/tests/gen-insn-x86-dat.sh b/tools/perf/arch/x86/tests/gen-insn-x86-dat.sh
new file mode 100755
index 000000000000..2d4ef94cff98
--- /dev/null
+++ b/tools/perf/arch/x86/tests/gen-insn-x86-dat.sh
@@ -0,0 +1,43 @@
1#!/bin/sh
2# gen-insn-x86-dat: generate data for the insn-x86 test
3# Copyright (c) 2015, 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
14set -e
15
16if [ "$(uname -m)" != "x86_64" ]; then
17 echo "ERROR: This script only works on x86_64"
18 exit 1
19fi
20
21cd $(dirname $0)
22
23trap 'echo "Might need a more recent version of binutils"' EXIT
24
25echo "Compiling insn-x86-dat-src.c to 64-bit object"
26
27gcc -g -c insn-x86-dat-src.c
28
29objdump -dSw insn-x86-dat-src.o | awk -f gen-insn-x86-dat.awk > insn-x86-dat-64.c
30
31rm -f insn-x86-dat-src.o
32
33echo "Compiling insn-x86-dat-src.c to 32-bit object"
34
35gcc -g -c -m32 insn-x86-dat-src.c
36
37objdump -dSw insn-x86-dat-src.o | awk -f gen-insn-x86-dat.awk > insn-x86-dat-32.c
38
39rm -f insn-x86-dat-src.o
40
41trap - EXIT
42
43echo "Done (use git diff to see the changes)"
diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-32.c b/tools/perf/arch/x86/tests/insn-x86-dat-32.c
new file mode 100644
index 000000000000..3b491cfe204e
--- /dev/null
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-32.c
@@ -0,0 +1,658 @@
1/*
2 * Generated by gen-insn-x86-dat.sh and gen-insn-x86-dat.awk
3 * from insn-x86-dat-src.c for inclusion by insn-x86.c
4 * Do not change this code.
5*/
6
7{{0x0f, 0x31, }, 2, 0, "", "",
8"0f 31 \trdtsc ",},
9{{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
10"f3 0f 1b 00 \tbndmk (%eax),%bnd0",},
11{{0xf3, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
12"f3 0f 1b 05 78 56 34 12 \tbndmk 0x12345678,%bnd0",},
13{{0xf3, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
14"f3 0f 1b 18 \tbndmk (%eax),%bnd3",},
15{{0xf3, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
16"f3 0f 1b 04 01 \tbndmk (%ecx,%eax,1),%bnd0",},
17{{0xf3, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
18"f3 0f 1b 04 05 78 56 34 12 \tbndmk 0x12345678(,%eax,1),%bnd0",},
19{{0xf3, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
20"f3 0f 1b 04 08 \tbndmk (%eax,%ecx,1),%bnd0",},
21{{0xf3, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
22"f3 0f 1b 04 c8 \tbndmk (%eax,%ecx,8),%bnd0",},
23{{0xf3, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
24"f3 0f 1b 40 12 \tbndmk 0x12(%eax),%bnd0",},
25{{0xf3, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
26"f3 0f 1b 45 12 \tbndmk 0x12(%ebp),%bnd0",},
27{{0xf3, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
28"f3 0f 1b 44 01 12 \tbndmk 0x12(%ecx,%eax,1),%bnd0",},
29{{0xf3, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
30"f3 0f 1b 44 05 12 \tbndmk 0x12(%ebp,%eax,1),%bnd0",},
31{{0xf3, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
32"f3 0f 1b 44 08 12 \tbndmk 0x12(%eax,%ecx,1),%bnd0",},
33{{0xf3, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
34"f3 0f 1b 44 c8 12 \tbndmk 0x12(%eax,%ecx,8),%bnd0",},
35{{0xf3, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
36"f3 0f 1b 80 78 56 34 12 \tbndmk 0x12345678(%eax),%bnd0",},
37{{0xf3, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
38"f3 0f 1b 85 78 56 34 12 \tbndmk 0x12345678(%ebp),%bnd0",},
39{{0xf3, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
40"f3 0f 1b 84 01 78 56 34 12 \tbndmk 0x12345678(%ecx,%eax,1),%bnd0",},
41{{0xf3, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
42"f3 0f 1b 84 05 78 56 34 12 \tbndmk 0x12345678(%ebp,%eax,1),%bnd0",},
43{{0xf3, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
44"f3 0f 1b 84 08 78 56 34 12 \tbndmk 0x12345678(%eax,%ecx,1),%bnd0",},
45{{0xf3, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
46"f3 0f 1b 84 c8 78 56 34 12 \tbndmk 0x12345678(%eax,%ecx,8),%bnd0",},
47{{0xf3, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
48"f3 0f 1a 00 \tbndcl (%eax),%bnd0",},
49{{0xf3, 0x0f, 0x1a, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
50"f3 0f 1a 05 78 56 34 12 \tbndcl 0x12345678,%bnd0",},
51{{0xf3, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
52"f3 0f 1a 18 \tbndcl (%eax),%bnd3",},
53{{0xf3, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
54"f3 0f 1a 04 01 \tbndcl (%ecx,%eax,1),%bnd0",},
55{{0xf3, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
56"f3 0f 1a 04 05 78 56 34 12 \tbndcl 0x12345678(,%eax,1),%bnd0",},
57{{0xf3, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
58"f3 0f 1a 04 08 \tbndcl (%eax,%ecx,1),%bnd0",},
59{{0xf3, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
60"f3 0f 1a 04 c8 \tbndcl (%eax,%ecx,8),%bnd0",},
61{{0xf3, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
62"f3 0f 1a 40 12 \tbndcl 0x12(%eax),%bnd0",},
63{{0xf3, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
64"f3 0f 1a 45 12 \tbndcl 0x12(%ebp),%bnd0",},
65{{0xf3, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
66"f3 0f 1a 44 01 12 \tbndcl 0x12(%ecx,%eax,1),%bnd0",},
67{{0xf3, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
68"f3 0f 1a 44 05 12 \tbndcl 0x12(%ebp,%eax,1),%bnd0",},
69{{0xf3, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
70"f3 0f 1a 44 08 12 \tbndcl 0x12(%eax,%ecx,1),%bnd0",},
71{{0xf3, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
72"f3 0f 1a 44 c8 12 \tbndcl 0x12(%eax,%ecx,8),%bnd0",},
73{{0xf3, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
74"f3 0f 1a 80 78 56 34 12 \tbndcl 0x12345678(%eax),%bnd0",},
75{{0xf3, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
76"f3 0f 1a 85 78 56 34 12 \tbndcl 0x12345678(%ebp),%bnd0",},
77{{0xf3, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
78"f3 0f 1a 84 01 78 56 34 12 \tbndcl 0x12345678(%ecx,%eax,1),%bnd0",},
79{{0xf3, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
80"f3 0f 1a 84 05 78 56 34 12 \tbndcl 0x12345678(%ebp,%eax,1),%bnd0",},
81{{0xf3, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
82"f3 0f 1a 84 08 78 56 34 12 \tbndcl 0x12345678(%eax,%ecx,1),%bnd0",},
83{{0xf3, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
84"f3 0f 1a 84 c8 78 56 34 12 \tbndcl 0x12345678(%eax,%ecx,8),%bnd0",},
85{{0xf3, 0x0f, 0x1a, 0xc0, }, 4, 0, "", "",
86"f3 0f 1a c0 \tbndcl %eax,%bnd0",},
87{{0xf2, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
88"f2 0f 1a 00 \tbndcu (%eax),%bnd0",},
89{{0xf2, 0x0f, 0x1a, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
90"f2 0f 1a 05 78 56 34 12 \tbndcu 0x12345678,%bnd0",},
91{{0xf2, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
92"f2 0f 1a 18 \tbndcu (%eax),%bnd3",},
93{{0xf2, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
94"f2 0f 1a 04 01 \tbndcu (%ecx,%eax,1),%bnd0",},
95{{0xf2, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
96"f2 0f 1a 04 05 78 56 34 12 \tbndcu 0x12345678(,%eax,1),%bnd0",},
97{{0xf2, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
98"f2 0f 1a 04 08 \tbndcu (%eax,%ecx,1),%bnd0",},
99{{0xf2, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
100"f2 0f 1a 04 c8 \tbndcu (%eax,%ecx,8),%bnd0",},
101{{0xf2, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
102"f2 0f 1a 40 12 \tbndcu 0x12(%eax),%bnd0",},
103{{0xf2, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
104"f2 0f 1a 45 12 \tbndcu 0x12(%ebp),%bnd0",},
105{{0xf2, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
106"f2 0f 1a 44 01 12 \tbndcu 0x12(%ecx,%eax,1),%bnd0",},
107{{0xf2, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
108"f2 0f 1a 44 05 12 \tbndcu 0x12(%ebp,%eax,1),%bnd0",},
109{{0xf2, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
110"f2 0f 1a 44 08 12 \tbndcu 0x12(%eax,%ecx,1),%bnd0",},
111{{0xf2, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
112"f2 0f 1a 44 c8 12 \tbndcu 0x12(%eax,%ecx,8),%bnd0",},
113{{0xf2, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
114"f2 0f 1a 80 78 56 34 12 \tbndcu 0x12345678(%eax),%bnd0",},
115{{0xf2, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
116"f2 0f 1a 85 78 56 34 12 \tbndcu 0x12345678(%ebp),%bnd0",},
117{{0xf2, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
118"f2 0f 1a 84 01 78 56 34 12 \tbndcu 0x12345678(%ecx,%eax,1),%bnd0",},
119{{0xf2, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
120"f2 0f 1a 84 05 78 56 34 12 \tbndcu 0x12345678(%ebp,%eax,1),%bnd0",},
121{{0xf2, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
122"f2 0f 1a 84 08 78 56 34 12 \tbndcu 0x12345678(%eax,%ecx,1),%bnd0",},
123{{0xf2, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
124"f2 0f 1a 84 c8 78 56 34 12 \tbndcu 0x12345678(%eax,%ecx,8),%bnd0",},
125{{0xf2, 0x0f, 0x1a, 0xc0, }, 4, 0, "", "",
126"f2 0f 1a c0 \tbndcu %eax,%bnd0",},
127{{0xf2, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
128"f2 0f 1b 00 \tbndcn (%eax),%bnd0",},
129{{0xf2, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
130"f2 0f 1b 05 78 56 34 12 \tbndcn 0x12345678,%bnd0",},
131{{0xf2, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
132"f2 0f 1b 18 \tbndcn (%eax),%bnd3",},
133{{0xf2, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
134"f2 0f 1b 04 01 \tbndcn (%ecx,%eax,1),%bnd0",},
135{{0xf2, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
136"f2 0f 1b 04 05 78 56 34 12 \tbndcn 0x12345678(,%eax,1),%bnd0",},
137{{0xf2, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
138"f2 0f 1b 04 08 \tbndcn (%eax,%ecx,1),%bnd0",},
139{{0xf2, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
140"f2 0f 1b 04 c8 \tbndcn (%eax,%ecx,8),%bnd0",},
141{{0xf2, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
142"f2 0f 1b 40 12 \tbndcn 0x12(%eax),%bnd0",},
143{{0xf2, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
144"f2 0f 1b 45 12 \tbndcn 0x12(%ebp),%bnd0",},
145{{0xf2, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
146"f2 0f 1b 44 01 12 \tbndcn 0x12(%ecx,%eax,1),%bnd0",},
147{{0xf2, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
148"f2 0f 1b 44 05 12 \tbndcn 0x12(%ebp,%eax,1),%bnd0",},
149{{0xf2, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
150"f2 0f 1b 44 08 12 \tbndcn 0x12(%eax,%ecx,1),%bnd0",},
151{{0xf2, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
152"f2 0f 1b 44 c8 12 \tbndcn 0x12(%eax,%ecx,8),%bnd0",},
153{{0xf2, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
154"f2 0f 1b 80 78 56 34 12 \tbndcn 0x12345678(%eax),%bnd0",},
155{{0xf2, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
156"f2 0f 1b 85 78 56 34 12 \tbndcn 0x12345678(%ebp),%bnd0",},
157{{0xf2, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
158"f2 0f 1b 84 01 78 56 34 12 \tbndcn 0x12345678(%ecx,%eax,1),%bnd0",},
159{{0xf2, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
160"f2 0f 1b 84 05 78 56 34 12 \tbndcn 0x12345678(%ebp,%eax,1),%bnd0",},
161{{0xf2, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
162"f2 0f 1b 84 08 78 56 34 12 \tbndcn 0x12345678(%eax,%ecx,1),%bnd0",},
163{{0xf2, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
164"f2 0f 1b 84 c8 78 56 34 12 \tbndcn 0x12345678(%eax,%ecx,8),%bnd0",},
165{{0xf2, 0x0f, 0x1b, 0xc0, }, 4, 0, "", "",
166"f2 0f 1b c0 \tbndcn %eax,%bnd0",},
167{{0x66, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
168"66 0f 1a 00 \tbndmov (%eax),%bnd0",},
169{{0x66, 0x0f, 0x1a, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
170"66 0f 1a 05 78 56 34 12 \tbndmov 0x12345678,%bnd0",},
171{{0x66, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
172"66 0f 1a 18 \tbndmov (%eax),%bnd3",},
173{{0x66, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
174"66 0f 1a 04 01 \tbndmov (%ecx,%eax,1),%bnd0",},
175{{0x66, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
176"66 0f 1a 04 05 78 56 34 12 \tbndmov 0x12345678(,%eax,1),%bnd0",},
177{{0x66, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
178"66 0f 1a 04 08 \tbndmov (%eax,%ecx,1),%bnd0",},
179{{0x66, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
180"66 0f 1a 04 c8 \tbndmov (%eax,%ecx,8),%bnd0",},
181{{0x66, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
182"66 0f 1a 40 12 \tbndmov 0x12(%eax),%bnd0",},
183{{0x66, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
184"66 0f 1a 45 12 \tbndmov 0x12(%ebp),%bnd0",},
185{{0x66, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
186"66 0f 1a 44 01 12 \tbndmov 0x12(%ecx,%eax,1),%bnd0",},
187{{0x66, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
188"66 0f 1a 44 05 12 \tbndmov 0x12(%ebp,%eax,1),%bnd0",},
189{{0x66, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
190"66 0f 1a 44 08 12 \tbndmov 0x12(%eax,%ecx,1),%bnd0",},
191{{0x66, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
192"66 0f 1a 44 c8 12 \tbndmov 0x12(%eax,%ecx,8),%bnd0",},
193{{0x66, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
194"66 0f 1a 80 78 56 34 12 \tbndmov 0x12345678(%eax),%bnd0",},
195{{0x66, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
196"66 0f 1a 85 78 56 34 12 \tbndmov 0x12345678(%ebp),%bnd0",},
197{{0x66, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
198"66 0f 1a 84 01 78 56 34 12 \tbndmov 0x12345678(%ecx,%eax,1),%bnd0",},
199{{0x66, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
200"66 0f 1a 84 05 78 56 34 12 \tbndmov 0x12345678(%ebp,%eax,1),%bnd0",},
201{{0x66, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
202"66 0f 1a 84 08 78 56 34 12 \tbndmov 0x12345678(%eax,%ecx,1),%bnd0",},
203{{0x66, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
204"66 0f 1a 84 c8 78 56 34 12 \tbndmov 0x12345678(%eax,%ecx,8),%bnd0",},
205{{0x66, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
206"66 0f 1b 00 \tbndmov %bnd0,(%eax)",},
207{{0x66, 0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
208"66 0f 1b 05 78 56 34 12 \tbndmov %bnd0,0x12345678",},
209{{0x66, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
210"66 0f 1b 18 \tbndmov %bnd3,(%eax)",},
211{{0x66, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
212"66 0f 1b 04 01 \tbndmov %bnd0,(%ecx,%eax,1)",},
213{{0x66, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
214"66 0f 1b 04 05 78 56 34 12 \tbndmov %bnd0,0x12345678(,%eax,1)",},
215{{0x66, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
216"66 0f 1b 04 08 \tbndmov %bnd0,(%eax,%ecx,1)",},
217{{0x66, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
218"66 0f 1b 04 c8 \tbndmov %bnd0,(%eax,%ecx,8)",},
219{{0x66, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
220"66 0f 1b 40 12 \tbndmov %bnd0,0x12(%eax)",},
221{{0x66, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
222"66 0f 1b 45 12 \tbndmov %bnd0,0x12(%ebp)",},
223{{0x66, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
224"66 0f 1b 44 01 12 \tbndmov %bnd0,0x12(%ecx,%eax,1)",},
225{{0x66, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
226"66 0f 1b 44 05 12 \tbndmov %bnd0,0x12(%ebp,%eax,1)",},
227{{0x66, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
228"66 0f 1b 44 08 12 \tbndmov %bnd0,0x12(%eax,%ecx,1)",},
229{{0x66, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
230"66 0f 1b 44 c8 12 \tbndmov %bnd0,0x12(%eax,%ecx,8)",},
231{{0x66, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
232"66 0f 1b 80 78 56 34 12 \tbndmov %bnd0,0x12345678(%eax)",},
233{{0x66, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
234"66 0f 1b 85 78 56 34 12 \tbndmov %bnd0,0x12345678(%ebp)",},
235{{0x66, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
236"66 0f 1b 84 01 78 56 34 12 \tbndmov %bnd0,0x12345678(%ecx,%eax,1)",},
237{{0x66, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
238"66 0f 1b 84 05 78 56 34 12 \tbndmov %bnd0,0x12345678(%ebp,%eax,1)",},
239{{0x66, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
240"66 0f 1b 84 08 78 56 34 12 \tbndmov %bnd0,0x12345678(%eax,%ecx,1)",},
241{{0x66, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
242"66 0f 1b 84 c8 78 56 34 12 \tbndmov %bnd0,0x12345678(%eax,%ecx,8)",},
243{{0x66, 0x0f, 0x1a, 0xc8, }, 4, 0, "", "",
244"66 0f 1a c8 \tbndmov %bnd0,%bnd1",},
245{{0x66, 0x0f, 0x1a, 0xc1, }, 4, 0, "", "",
246"66 0f 1a c1 \tbndmov %bnd1,%bnd0",},
247{{0x0f, 0x1a, 0x00, }, 3, 0, "", "",
248"0f 1a 00 \tbndldx (%eax),%bnd0",},
249{{0x0f, 0x1a, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
250"0f 1a 05 78 56 34 12 \tbndldx 0x12345678,%bnd0",},
251{{0x0f, 0x1a, 0x18, }, 3, 0, "", "",
252"0f 1a 18 \tbndldx (%eax),%bnd3",},
253{{0x0f, 0x1a, 0x04, 0x01, }, 4, 0, "", "",
254"0f 1a 04 01 \tbndldx (%ecx,%eax,1),%bnd0",},
255{{0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
256"0f 1a 04 05 78 56 34 12 \tbndldx 0x12345678(,%eax,1),%bnd0",},
257{{0x0f, 0x1a, 0x04, 0x08, }, 4, 0, "", "",
258"0f 1a 04 08 \tbndldx (%eax,%ecx,1),%bnd0",},
259{{0x0f, 0x1a, 0x40, 0x12, }, 4, 0, "", "",
260"0f 1a 40 12 \tbndldx 0x12(%eax),%bnd0",},
261{{0x0f, 0x1a, 0x45, 0x12, }, 4, 0, "", "",
262"0f 1a 45 12 \tbndldx 0x12(%ebp),%bnd0",},
263{{0x0f, 0x1a, 0x44, 0x01, 0x12, }, 5, 0, "", "",
264"0f 1a 44 01 12 \tbndldx 0x12(%ecx,%eax,1),%bnd0",},
265{{0x0f, 0x1a, 0x44, 0x05, 0x12, }, 5, 0, "", "",
266"0f 1a 44 05 12 \tbndldx 0x12(%ebp,%eax,1),%bnd0",},
267{{0x0f, 0x1a, 0x44, 0x08, 0x12, }, 5, 0, "", "",
268"0f 1a 44 08 12 \tbndldx 0x12(%eax,%ecx,1),%bnd0",},
269{{0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
270"0f 1a 80 78 56 34 12 \tbndldx 0x12345678(%eax),%bnd0",},
271{{0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
272"0f 1a 85 78 56 34 12 \tbndldx 0x12345678(%ebp),%bnd0",},
273{{0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
274"0f 1a 84 01 78 56 34 12 \tbndldx 0x12345678(%ecx,%eax,1),%bnd0",},
275{{0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
276"0f 1a 84 05 78 56 34 12 \tbndldx 0x12345678(%ebp,%eax,1),%bnd0",},
277{{0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
278"0f 1a 84 08 78 56 34 12 \tbndldx 0x12345678(%eax,%ecx,1),%bnd0",},
279{{0x0f, 0x1b, 0x00, }, 3, 0, "", "",
280"0f 1b 00 \tbndstx %bnd0,(%eax)",},
281{{0x0f, 0x1b, 0x05, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
282"0f 1b 05 78 56 34 12 \tbndstx %bnd0,0x12345678",},
283{{0x0f, 0x1b, 0x18, }, 3, 0, "", "",
284"0f 1b 18 \tbndstx %bnd3,(%eax)",},
285{{0x0f, 0x1b, 0x04, 0x01, }, 4, 0, "", "",
286"0f 1b 04 01 \tbndstx %bnd0,(%ecx,%eax,1)",},
287{{0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
288"0f 1b 04 05 78 56 34 12 \tbndstx %bnd0,0x12345678(,%eax,1)",},
289{{0x0f, 0x1b, 0x04, 0x08, }, 4, 0, "", "",
290"0f 1b 04 08 \tbndstx %bnd0,(%eax,%ecx,1)",},
291{{0x0f, 0x1b, 0x40, 0x12, }, 4, 0, "", "",
292"0f 1b 40 12 \tbndstx %bnd0,0x12(%eax)",},
293{{0x0f, 0x1b, 0x45, 0x12, }, 4, 0, "", "",
294"0f 1b 45 12 \tbndstx %bnd0,0x12(%ebp)",},
295{{0x0f, 0x1b, 0x44, 0x01, 0x12, }, 5, 0, "", "",
296"0f 1b 44 01 12 \tbndstx %bnd0,0x12(%ecx,%eax,1)",},
297{{0x0f, 0x1b, 0x44, 0x05, 0x12, }, 5, 0, "", "",
298"0f 1b 44 05 12 \tbndstx %bnd0,0x12(%ebp,%eax,1)",},
299{{0x0f, 0x1b, 0x44, 0x08, 0x12, }, 5, 0, "", "",
300"0f 1b 44 08 12 \tbndstx %bnd0,0x12(%eax,%ecx,1)",},
301{{0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
302"0f 1b 80 78 56 34 12 \tbndstx %bnd0,0x12345678(%eax)",},
303{{0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
304"0f 1b 85 78 56 34 12 \tbndstx %bnd0,0x12345678(%ebp)",},
305{{0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
306"0f 1b 84 01 78 56 34 12 \tbndstx %bnd0,0x12345678(%ecx,%eax,1)",},
307{{0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
308"0f 1b 84 05 78 56 34 12 \tbndstx %bnd0,0x12345678(%ebp,%eax,1)",},
309{{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)",},
311{{0xf2, 0xe8, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "call", "unconditional",
312"f2 e8 fc ff ff ff \tbnd call 3c3 <main+0x3c3>",},
313{{0xf2, 0xff, 0x10, }, 3, 0, "call", "indirect",
314"f2 ff 10 \tbnd call *(%eax)",},
315{{0xf2, 0xc3, }, 2, 0, "ret", "indirect",
316"f2 c3 \tbnd ret ",},
317{{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional",
318"f2 e9 fc ff ff ff \tbnd jmp 3ce <main+0x3ce>",},
319{{0xf2, 0xe9, 0xfc, 0xff, 0xff, 0xff, }, 6, 0xfffffffc, "jmp", "unconditional",
320"f2 e9 fc ff ff ff \tbnd jmp 3d4 <main+0x3d4>",},
321{{0xf2, 0xff, 0x21, }, 3, 0, "jmp", "indirect",
322"f2 ff 21 \tbnd jmp *(%ecx)",},
323{{0xf2, 0x0f, 0x85, 0xfc, 0xff, 0xff, 0xff, }, 7, 0xfffffffc, "jcc", "conditional",
324"f2 0f 85 fc ff ff ff \tbnd jne 3de <main+0x3de>",},
325{{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "",
326"0f 3a cc c1 00 \tsha1rnds4 $0x0,%xmm1,%xmm0",},
327{{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "",
328"0f 3a cc d7 91 \tsha1rnds4 $0x91,%xmm7,%xmm2",},
329{{0x0f, 0x3a, 0xcc, 0x00, 0x91, }, 5, 0, "", "",
330"0f 3a cc 00 91 \tsha1rnds4 $0x91,(%eax),%xmm0",},
331{{0x0f, 0x3a, 0xcc, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
332"0f 3a cc 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678,%xmm0",},
333{{0x0f, 0x3a, 0xcc, 0x18, 0x91, }, 5, 0, "", "",
334"0f 3a cc 18 91 \tsha1rnds4 $0x91,(%eax),%xmm3",},
335{{0x0f, 0x3a, 0xcc, 0x04, 0x01, 0x91, }, 6, 0, "", "",
336"0f 3a cc 04 01 91 \tsha1rnds4 $0x91,(%ecx,%eax,1),%xmm0",},
337{{0x0f, 0x3a, 0xcc, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
338"0f 3a cc 04 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(,%eax,1),%xmm0",},
339{{0x0f, 0x3a, 0xcc, 0x04, 0x08, 0x91, }, 6, 0, "", "",
340"0f 3a cc 04 08 91 \tsha1rnds4 $0x91,(%eax,%ecx,1),%xmm0",},
341{{0x0f, 0x3a, 0xcc, 0x04, 0xc8, 0x91, }, 6, 0, "", "",
342"0f 3a cc 04 c8 91 \tsha1rnds4 $0x91,(%eax,%ecx,8),%xmm0",},
343{{0x0f, 0x3a, 0xcc, 0x40, 0x12, 0x91, }, 6, 0, "", "",
344"0f 3a cc 40 12 91 \tsha1rnds4 $0x91,0x12(%eax),%xmm0",},
345{{0x0f, 0x3a, 0xcc, 0x45, 0x12, 0x91, }, 6, 0, "", "",
346"0f 3a cc 45 12 91 \tsha1rnds4 $0x91,0x12(%ebp),%xmm0",},
347{{0x0f, 0x3a, 0xcc, 0x44, 0x01, 0x12, 0x91, }, 7, 0, "", "",
348"0f 3a cc 44 01 12 91 \tsha1rnds4 $0x91,0x12(%ecx,%eax,1),%xmm0",},
349{{0x0f, 0x3a, 0xcc, 0x44, 0x05, 0x12, 0x91, }, 7, 0, "", "",
350"0f 3a cc 44 05 12 91 \tsha1rnds4 $0x91,0x12(%ebp,%eax,1),%xmm0",},
351{{0x0f, 0x3a, 0xcc, 0x44, 0x08, 0x12, 0x91, }, 7, 0, "", "",
352"0f 3a cc 44 08 12 91 \tsha1rnds4 $0x91,0x12(%eax,%ecx,1),%xmm0",},
353{{0x0f, 0x3a, 0xcc, 0x44, 0xc8, 0x12, 0x91, }, 7, 0, "", "",
354"0f 3a cc 44 c8 12 91 \tsha1rnds4 $0x91,0x12(%eax,%ecx,8),%xmm0",},
355{{0x0f, 0x3a, 0xcc, 0x80, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
356"0f 3a cc 80 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%eax),%xmm0",},
357{{0x0f, 0x3a, 0xcc, 0x85, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
358"0f 3a cc 85 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%ebp),%xmm0",},
359{{0x0f, 0x3a, 0xcc, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
360"0f 3a cc 84 01 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%ecx,%eax,1),%xmm0",},
361{{0x0f, 0x3a, 0xcc, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
362"0f 3a cc 84 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%ebp,%eax,1),%xmm0",},
363{{0x0f, 0x3a, 0xcc, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
364"0f 3a cc 84 08 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%eax,%ecx,1),%xmm0",},
365{{0x0f, 0x3a, 0xcc, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
366"0f 3a cc 84 c8 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%eax,%ecx,8),%xmm0",},
367{{0x0f, 0x38, 0xc8, 0xc1, }, 4, 0, "", "",
368"0f 38 c8 c1 \tsha1nexte %xmm1,%xmm0",},
369{{0x0f, 0x38, 0xc8, 0xd7, }, 4, 0, "", "",
370"0f 38 c8 d7 \tsha1nexte %xmm7,%xmm2",},
371{{0x0f, 0x38, 0xc8, 0x00, }, 4, 0, "", "",
372"0f 38 c8 00 \tsha1nexte (%eax),%xmm0",},
373{{0x0f, 0x38, 0xc8, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
374"0f 38 c8 05 78 56 34 12 \tsha1nexte 0x12345678,%xmm0",},
375{{0x0f, 0x38, 0xc8, 0x18, }, 4, 0, "", "",
376"0f 38 c8 18 \tsha1nexte (%eax),%xmm3",},
377{{0x0f, 0x38, 0xc8, 0x04, 0x01, }, 5, 0, "", "",
378"0f 38 c8 04 01 \tsha1nexte (%ecx,%eax,1),%xmm0",},
379{{0x0f, 0x38, 0xc8, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
380"0f 38 c8 04 05 78 56 34 12 \tsha1nexte 0x12345678(,%eax,1),%xmm0",},
381{{0x0f, 0x38, 0xc8, 0x04, 0x08, }, 5, 0, "", "",
382"0f 38 c8 04 08 \tsha1nexte (%eax,%ecx,1),%xmm0",},
383{{0x0f, 0x38, 0xc8, 0x04, 0xc8, }, 5, 0, "", "",
384"0f 38 c8 04 c8 \tsha1nexte (%eax,%ecx,8),%xmm0",},
385{{0x0f, 0x38, 0xc8, 0x40, 0x12, }, 5, 0, "", "",
386"0f 38 c8 40 12 \tsha1nexte 0x12(%eax),%xmm0",},
387{{0x0f, 0x38, 0xc8, 0x45, 0x12, }, 5, 0, "", "",
388"0f 38 c8 45 12 \tsha1nexte 0x12(%ebp),%xmm0",},
389{{0x0f, 0x38, 0xc8, 0x44, 0x01, 0x12, }, 6, 0, "", "",
390"0f 38 c8 44 01 12 \tsha1nexte 0x12(%ecx,%eax,1),%xmm0",},
391{{0x0f, 0x38, 0xc8, 0x44, 0x05, 0x12, }, 6, 0, "", "",
392"0f 38 c8 44 05 12 \tsha1nexte 0x12(%ebp,%eax,1),%xmm0",},
393{{0x0f, 0x38, 0xc8, 0x44, 0x08, 0x12, }, 6, 0, "", "",
394"0f 38 c8 44 08 12 \tsha1nexte 0x12(%eax,%ecx,1),%xmm0",},
395{{0x0f, 0x38, 0xc8, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
396"0f 38 c8 44 c8 12 \tsha1nexte 0x12(%eax,%ecx,8),%xmm0",},
397{{0x0f, 0x38, 0xc8, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
398"0f 38 c8 80 78 56 34 12 \tsha1nexte 0x12345678(%eax),%xmm0",},
399{{0x0f, 0x38, 0xc8, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
400"0f 38 c8 85 78 56 34 12 \tsha1nexte 0x12345678(%ebp),%xmm0",},
401{{0x0f, 0x38, 0xc8, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
402"0f 38 c8 84 01 78 56 34 12 \tsha1nexte 0x12345678(%ecx,%eax,1),%xmm0",},
403{{0x0f, 0x38, 0xc8, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
404"0f 38 c8 84 05 78 56 34 12 \tsha1nexte 0x12345678(%ebp,%eax,1),%xmm0",},
405{{0x0f, 0x38, 0xc8, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
406"0f 38 c8 84 08 78 56 34 12 \tsha1nexte 0x12345678(%eax,%ecx,1),%xmm0",},
407{{0x0f, 0x38, 0xc8, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
408"0f 38 c8 84 c8 78 56 34 12 \tsha1nexte 0x12345678(%eax,%ecx,8),%xmm0",},
409{{0x0f, 0x38, 0xc9, 0xc1, }, 4, 0, "", "",
410"0f 38 c9 c1 \tsha1msg1 %xmm1,%xmm0",},
411{{0x0f, 0x38, 0xc9, 0xd7, }, 4, 0, "", "",
412"0f 38 c9 d7 \tsha1msg1 %xmm7,%xmm2",},
413{{0x0f, 0x38, 0xc9, 0x00, }, 4, 0, "", "",
414"0f 38 c9 00 \tsha1msg1 (%eax),%xmm0",},
415{{0x0f, 0x38, 0xc9, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
416"0f 38 c9 05 78 56 34 12 \tsha1msg1 0x12345678,%xmm0",},
417{{0x0f, 0x38, 0xc9, 0x18, }, 4, 0, "", "",
418"0f 38 c9 18 \tsha1msg1 (%eax),%xmm3",},
419{{0x0f, 0x38, 0xc9, 0x04, 0x01, }, 5, 0, "", "",
420"0f 38 c9 04 01 \tsha1msg1 (%ecx,%eax,1),%xmm0",},
421{{0x0f, 0x38, 0xc9, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
422"0f 38 c9 04 05 78 56 34 12 \tsha1msg1 0x12345678(,%eax,1),%xmm0",},
423{{0x0f, 0x38, 0xc9, 0x04, 0x08, }, 5, 0, "", "",
424"0f 38 c9 04 08 \tsha1msg1 (%eax,%ecx,1),%xmm0",},
425{{0x0f, 0x38, 0xc9, 0x04, 0xc8, }, 5, 0, "", "",
426"0f 38 c9 04 c8 \tsha1msg1 (%eax,%ecx,8),%xmm0",},
427{{0x0f, 0x38, 0xc9, 0x40, 0x12, }, 5, 0, "", "",
428"0f 38 c9 40 12 \tsha1msg1 0x12(%eax),%xmm0",},
429{{0x0f, 0x38, 0xc9, 0x45, 0x12, }, 5, 0, "", "",
430"0f 38 c9 45 12 \tsha1msg1 0x12(%ebp),%xmm0",},
431{{0x0f, 0x38, 0xc9, 0x44, 0x01, 0x12, }, 6, 0, "", "",
432"0f 38 c9 44 01 12 \tsha1msg1 0x12(%ecx,%eax,1),%xmm0",},
433{{0x0f, 0x38, 0xc9, 0x44, 0x05, 0x12, }, 6, 0, "", "",
434"0f 38 c9 44 05 12 \tsha1msg1 0x12(%ebp,%eax,1),%xmm0",},
435{{0x0f, 0x38, 0xc9, 0x44, 0x08, 0x12, }, 6, 0, "", "",
436"0f 38 c9 44 08 12 \tsha1msg1 0x12(%eax,%ecx,1),%xmm0",},
437{{0x0f, 0x38, 0xc9, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
438"0f 38 c9 44 c8 12 \tsha1msg1 0x12(%eax,%ecx,8),%xmm0",},
439{{0x0f, 0x38, 0xc9, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
440"0f 38 c9 80 78 56 34 12 \tsha1msg1 0x12345678(%eax),%xmm0",},
441{{0x0f, 0x38, 0xc9, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
442"0f 38 c9 85 78 56 34 12 \tsha1msg1 0x12345678(%ebp),%xmm0",},
443{{0x0f, 0x38, 0xc9, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
444"0f 38 c9 84 01 78 56 34 12 \tsha1msg1 0x12345678(%ecx,%eax,1),%xmm0",},
445{{0x0f, 0x38, 0xc9, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
446"0f 38 c9 84 05 78 56 34 12 \tsha1msg1 0x12345678(%ebp,%eax,1),%xmm0",},
447{{0x0f, 0x38, 0xc9, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
448"0f 38 c9 84 08 78 56 34 12 \tsha1msg1 0x12345678(%eax,%ecx,1),%xmm0",},
449{{0x0f, 0x38, 0xc9, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
450"0f 38 c9 84 c8 78 56 34 12 \tsha1msg1 0x12345678(%eax,%ecx,8),%xmm0",},
451{{0x0f, 0x38, 0xca, 0xc1, }, 4, 0, "", "",
452"0f 38 ca c1 \tsha1msg2 %xmm1,%xmm0",},
453{{0x0f, 0x38, 0xca, 0xd7, }, 4, 0, "", "",
454"0f 38 ca d7 \tsha1msg2 %xmm7,%xmm2",},
455{{0x0f, 0x38, 0xca, 0x00, }, 4, 0, "", "",
456"0f 38 ca 00 \tsha1msg2 (%eax),%xmm0",},
457{{0x0f, 0x38, 0xca, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
458"0f 38 ca 05 78 56 34 12 \tsha1msg2 0x12345678,%xmm0",},
459{{0x0f, 0x38, 0xca, 0x18, }, 4, 0, "", "",
460"0f 38 ca 18 \tsha1msg2 (%eax),%xmm3",},
461{{0x0f, 0x38, 0xca, 0x04, 0x01, }, 5, 0, "", "",
462"0f 38 ca 04 01 \tsha1msg2 (%ecx,%eax,1),%xmm0",},
463{{0x0f, 0x38, 0xca, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
464"0f 38 ca 04 05 78 56 34 12 \tsha1msg2 0x12345678(,%eax,1),%xmm0",},
465{{0x0f, 0x38, 0xca, 0x04, 0x08, }, 5, 0, "", "",
466"0f 38 ca 04 08 \tsha1msg2 (%eax,%ecx,1),%xmm0",},
467{{0x0f, 0x38, 0xca, 0x04, 0xc8, }, 5, 0, "", "",
468"0f 38 ca 04 c8 \tsha1msg2 (%eax,%ecx,8),%xmm0",},
469{{0x0f, 0x38, 0xca, 0x40, 0x12, }, 5, 0, "", "",
470"0f 38 ca 40 12 \tsha1msg2 0x12(%eax),%xmm0",},
471{{0x0f, 0x38, 0xca, 0x45, 0x12, }, 5, 0, "", "",
472"0f 38 ca 45 12 \tsha1msg2 0x12(%ebp),%xmm0",},
473{{0x0f, 0x38, 0xca, 0x44, 0x01, 0x12, }, 6, 0, "", "",
474"0f 38 ca 44 01 12 \tsha1msg2 0x12(%ecx,%eax,1),%xmm0",},
475{{0x0f, 0x38, 0xca, 0x44, 0x05, 0x12, }, 6, 0, "", "",
476"0f 38 ca 44 05 12 \tsha1msg2 0x12(%ebp,%eax,1),%xmm0",},
477{{0x0f, 0x38, 0xca, 0x44, 0x08, 0x12, }, 6, 0, "", "",
478"0f 38 ca 44 08 12 \tsha1msg2 0x12(%eax,%ecx,1),%xmm0",},
479{{0x0f, 0x38, 0xca, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
480"0f 38 ca 44 c8 12 \tsha1msg2 0x12(%eax,%ecx,8),%xmm0",},
481{{0x0f, 0x38, 0xca, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
482"0f 38 ca 80 78 56 34 12 \tsha1msg2 0x12345678(%eax),%xmm0",},
483{{0x0f, 0x38, 0xca, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
484"0f 38 ca 85 78 56 34 12 \tsha1msg2 0x12345678(%ebp),%xmm0",},
485{{0x0f, 0x38, 0xca, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
486"0f 38 ca 84 01 78 56 34 12 \tsha1msg2 0x12345678(%ecx,%eax,1),%xmm0",},
487{{0x0f, 0x38, 0xca, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
488"0f 38 ca 84 05 78 56 34 12 \tsha1msg2 0x12345678(%ebp,%eax,1),%xmm0",},
489{{0x0f, 0x38, 0xca, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
490"0f 38 ca 84 08 78 56 34 12 \tsha1msg2 0x12345678(%eax,%ecx,1),%xmm0",},
491{{0x0f, 0x38, 0xca, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
492"0f 38 ca 84 c8 78 56 34 12 \tsha1msg2 0x12345678(%eax,%ecx,8),%xmm0",},
493{{0x0f, 0x38, 0xcb, 0xcc, }, 4, 0, "", "",
494"0f 38 cb cc \tsha256rnds2 %xmm0,%xmm4,%xmm1",},
495{{0x0f, 0x38, 0xcb, 0xd7, }, 4, 0, "", "",
496"0f 38 cb d7 \tsha256rnds2 %xmm0,%xmm7,%xmm2",},
497{{0x0f, 0x38, 0xcb, 0x08, }, 4, 0, "", "",
498"0f 38 cb 08 \tsha256rnds2 %xmm0,(%eax),%xmm1",},
499{{0x0f, 0x38, 0xcb, 0x0d, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
500"0f 38 cb 0d 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678,%xmm1",},
501{{0x0f, 0x38, 0xcb, 0x18, }, 4, 0, "", "",
502"0f 38 cb 18 \tsha256rnds2 %xmm0,(%eax),%xmm3",},
503{{0x0f, 0x38, 0xcb, 0x0c, 0x01, }, 5, 0, "", "",
504"0f 38 cb 0c 01 \tsha256rnds2 %xmm0,(%ecx,%eax,1),%xmm1",},
505{{0x0f, 0x38, 0xcb, 0x0c, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
506"0f 38 cb 0c 05 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(,%eax,1),%xmm1",},
507{{0x0f, 0x38, 0xcb, 0x0c, 0x08, }, 5, 0, "", "",
508"0f 38 cb 0c 08 \tsha256rnds2 %xmm0,(%eax,%ecx,1),%xmm1",},
509{{0x0f, 0x38, 0xcb, 0x0c, 0xc8, }, 5, 0, "", "",
510"0f 38 cb 0c c8 \tsha256rnds2 %xmm0,(%eax,%ecx,8),%xmm1",},
511{{0x0f, 0x38, 0xcb, 0x48, 0x12, }, 5, 0, "", "",
512"0f 38 cb 48 12 \tsha256rnds2 %xmm0,0x12(%eax),%xmm1",},
513{{0x0f, 0x38, 0xcb, 0x4d, 0x12, }, 5, 0, "", "",
514"0f 38 cb 4d 12 \tsha256rnds2 %xmm0,0x12(%ebp),%xmm1",},
515{{0x0f, 0x38, 0xcb, 0x4c, 0x01, 0x12, }, 6, 0, "", "",
516"0f 38 cb 4c 01 12 \tsha256rnds2 %xmm0,0x12(%ecx,%eax,1),%xmm1",},
517{{0x0f, 0x38, 0xcb, 0x4c, 0x05, 0x12, }, 6, 0, "", "",
518"0f 38 cb 4c 05 12 \tsha256rnds2 %xmm0,0x12(%ebp,%eax,1),%xmm1",},
519{{0x0f, 0x38, 0xcb, 0x4c, 0x08, 0x12, }, 6, 0, "", "",
520"0f 38 cb 4c 08 12 \tsha256rnds2 %xmm0,0x12(%eax,%ecx,1),%xmm1",},
521{{0x0f, 0x38, 0xcb, 0x4c, 0xc8, 0x12, }, 6, 0, "", "",
522"0f 38 cb 4c c8 12 \tsha256rnds2 %xmm0,0x12(%eax,%ecx,8),%xmm1",},
523{{0x0f, 0x38, 0xcb, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
524"0f 38 cb 88 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%eax),%xmm1",},
525{{0x0f, 0x38, 0xcb, 0x8d, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
526"0f 38 cb 8d 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%ebp),%xmm1",},
527{{0x0f, 0x38, 0xcb, 0x8c, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
528"0f 38 cb 8c 01 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%ecx,%eax,1),%xmm1",},
529{{0x0f, 0x38, 0xcb, 0x8c, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
530"0f 38 cb 8c 05 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%ebp,%eax,1),%xmm1",},
531{{0x0f, 0x38, 0xcb, 0x8c, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
532"0f 38 cb 8c 08 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%eax,%ecx,1),%xmm1",},
533{{0x0f, 0x38, 0xcb, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
534"0f 38 cb 8c c8 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%eax,%ecx,8),%xmm1",},
535{{0x0f, 0x38, 0xcc, 0xc1, }, 4, 0, "", "",
536"0f 38 cc c1 \tsha256msg1 %xmm1,%xmm0",},
537{{0x0f, 0x38, 0xcc, 0xd7, }, 4, 0, "", "",
538"0f 38 cc d7 \tsha256msg1 %xmm7,%xmm2",},
539{{0x0f, 0x38, 0xcc, 0x00, }, 4, 0, "", "",
540"0f 38 cc 00 \tsha256msg1 (%eax),%xmm0",},
541{{0x0f, 0x38, 0xcc, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
542"0f 38 cc 05 78 56 34 12 \tsha256msg1 0x12345678,%xmm0",},
543{{0x0f, 0x38, 0xcc, 0x18, }, 4, 0, "", "",
544"0f 38 cc 18 \tsha256msg1 (%eax),%xmm3",},
545{{0x0f, 0x38, 0xcc, 0x04, 0x01, }, 5, 0, "", "",
546"0f 38 cc 04 01 \tsha256msg1 (%ecx,%eax,1),%xmm0",},
547{{0x0f, 0x38, 0xcc, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
548"0f 38 cc 04 05 78 56 34 12 \tsha256msg1 0x12345678(,%eax,1),%xmm0",},
549{{0x0f, 0x38, 0xcc, 0x04, 0x08, }, 5, 0, "", "",
550"0f 38 cc 04 08 \tsha256msg1 (%eax,%ecx,1),%xmm0",},
551{{0x0f, 0x38, 0xcc, 0x04, 0xc8, }, 5, 0, "", "",
552"0f 38 cc 04 c8 \tsha256msg1 (%eax,%ecx,8),%xmm0",},
553{{0x0f, 0x38, 0xcc, 0x40, 0x12, }, 5, 0, "", "",
554"0f 38 cc 40 12 \tsha256msg1 0x12(%eax),%xmm0",},
555{{0x0f, 0x38, 0xcc, 0x45, 0x12, }, 5, 0, "", "",
556"0f 38 cc 45 12 \tsha256msg1 0x12(%ebp),%xmm0",},
557{{0x0f, 0x38, 0xcc, 0x44, 0x01, 0x12, }, 6, 0, "", "",
558"0f 38 cc 44 01 12 \tsha256msg1 0x12(%ecx,%eax,1),%xmm0",},
559{{0x0f, 0x38, 0xcc, 0x44, 0x05, 0x12, }, 6, 0, "", "",
560"0f 38 cc 44 05 12 \tsha256msg1 0x12(%ebp,%eax,1),%xmm0",},
561{{0x0f, 0x38, 0xcc, 0x44, 0x08, 0x12, }, 6, 0, "", "",
562"0f 38 cc 44 08 12 \tsha256msg1 0x12(%eax,%ecx,1),%xmm0",},
563{{0x0f, 0x38, 0xcc, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
564"0f 38 cc 44 c8 12 \tsha256msg1 0x12(%eax,%ecx,8),%xmm0",},
565{{0x0f, 0x38, 0xcc, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
566"0f 38 cc 80 78 56 34 12 \tsha256msg1 0x12345678(%eax),%xmm0",},
567{{0x0f, 0x38, 0xcc, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
568"0f 38 cc 85 78 56 34 12 \tsha256msg1 0x12345678(%ebp),%xmm0",},
569{{0x0f, 0x38, 0xcc, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
570"0f 38 cc 84 01 78 56 34 12 \tsha256msg1 0x12345678(%ecx,%eax,1),%xmm0",},
571{{0x0f, 0x38, 0xcc, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
572"0f 38 cc 84 05 78 56 34 12 \tsha256msg1 0x12345678(%ebp,%eax,1),%xmm0",},
573{{0x0f, 0x38, 0xcc, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
574"0f 38 cc 84 08 78 56 34 12 \tsha256msg1 0x12345678(%eax,%ecx,1),%xmm0",},
575{{0x0f, 0x38, 0xcc, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
576"0f 38 cc 84 c8 78 56 34 12 \tsha256msg1 0x12345678(%eax,%ecx,8),%xmm0",},
577{{0x0f, 0x38, 0xcd, 0xc1, }, 4, 0, "", "",
578"0f 38 cd c1 \tsha256msg2 %xmm1,%xmm0",},
579{{0x0f, 0x38, 0xcd, 0xd7, }, 4, 0, "", "",
580"0f 38 cd d7 \tsha256msg2 %xmm7,%xmm2",},
581{{0x0f, 0x38, 0xcd, 0x00, }, 4, 0, "", "",
582"0f 38 cd 00 \tsha256msg2 (%eax),%xmm0",},
583{{0x0f, 0x38, 0xcd, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
584"0f 38 cd 05 78 56 34 12 \tsha256msg2 0x12345678,%xmm0",},
585{{0x0f, 0x38, 0xcd, 0x18, }, 4, 0, "", "",
586"0f 38 cd 18 \tsha256msg2 (%eax),%xmm3",},
587{{0x0f, 0x38, 0xcd, 0x04, 0x01, }, 5, 0, "", "",
588"0f 38 cd 04 01 \tsha256msg2 (%ecx,%eax,1),%xmm0",},
589{{0x0f, 0x38, 0xcd, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
590"0f 38 cd 04 05 78 56 34 12 \tsha256msg2 0x12345678(,%eax,1),%xmm0",},
591{{0x0f, 0x38, 0xcd, 0x04, 0x08, }, 5, 0, "", "",
592"0f 38 cd 04 08 \tsha256msg2 (%eax,%ecx,1),%xmm0",},
593{{0x0f, 0x38, 0xcd, 0x04, 0xc8, }, 5, 0, "", "",
594"0f 38 cd 04 c8 \tsha256msg2 (%eax,%ecx,8),%xmm0",},
595{{0x0f, 0x38, 0xcd, 0x40, 0x12, }, 5, 0, "", "",
596"0f 38 cd 40 12 \tsha256msg2 0x12(%eax),%xmm0",},
597{{0x0f, 0x38, 0xcd, 0x45, 0x12, }, 5, 0, "", "",
598"0f 38 cd 45 12 \tsha256msg2 0x12(%ebp),%xmm0",},
599{{0x0f, 0x38, 0xcd, 0x44, 0x01, 0x12, }, 6, 0, "", "",
600"0f 38 cd 44 01 12 \tsha256msg2 0x12(%ecx,%eax,1),%xmm0",},
601{{0x0f, 0x38, 0xcd, 0x44, 0x05, 0x12, }, 6, 0, "", "",
602"0f 38 cd 44 05 12 \tsha256msg2 0x12(%ebp,%eax,1),%xmm0",},
603{{0x0f, 0x38, 0xcd, 0x44, 0x08, 0x12, }, 6, 0, "", "",
604"0f 38 cd 44 08 12 \tsha256msg2 0x12(%eax,%ecx,1),%xmm0",},
605{{0x0f, 0x38, 0xcd, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
606"0f 38 cd 44 c8 12 \tsha256msg2 0x12(%eax,%ecx,8),%xmm0",},
607{{0x0f, 0x38, 0xcd, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
608"0f 38 cd 80 78 56 34 12 \tsha256msg2 0x12345678(%eax),%xmm0",},
609{{0x0f, 0x38, 0xcd, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
610"0f 38 cd 85 78 56 34 12 \tsha256msg2 0x12345678(%ebp),%xmm0",},
611{{0x0f, 0x38, 0xcd, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
612"0f 38 cd 84 01 78 56 34 12 \tsha256msg2 0x12345678(%ecx,%eax,1),%xmm0",},
613{{0x0f, 0x38, 0xcd, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
614"0f 38 cd 84 05 78 56 34 12 \tsha256msg2 0x12345678(%ebp,%eax,1),%xmm0",},
615{{0x0f, 0x38, 0xcd, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
616"0f 38 cd 84 08 78 56 34 12 \tsha256msg2 0x12345678(%eax,%ecx,1),%xmm0",},
617{{0x0f, 0x38, 0xcd, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
618"0f 38 cd 84 c8 78 56 34 12 \tsha256msg2 0x12345678(%eax,%ecx,8),%xmm0",},
619{{0x66, 0x0f, 0xae, 0x38, }, 4, 0, "", "",
620"66 0f ae 38 \tclflushopt (%eax)",},
621{{0x66, 0x0f, 0xae, 0x3d, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
622"66 0f ae 3d 78 56 34 12 \tclflushopt 0x12345678",},
623{{0x66, 0x0f, 0xae, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
624"66 0f ae bc c8 78 56 34 12 \tclflushopt 0x12345678(%eax,%ecx,8)",},
625{{0x0f, 0xae, 0x38, }, 3, 0, "", "",
626"0f ae 38 \tclflush (%eax)",},
627{{0x0f, 0xae, 0xf8, }, 3, 0, "", "",
628"0f ae f8 \tsfence ",},
629{{0x66, 0x0f, 0xae, 0x30, }, 4, 0, "", "",
630"66 0f ae 30 \tclwb (%eax)",},
631{{0x66, 0x0f, 0xae, 0x35, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
632"66 0f ae 35 78 56 34 12 \tclwb 0x12345678",},
633{{0x66, 0x0f, 0xae, 0xb4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
634"66 0f ae b4 c8 78 56 34 12 \tclwb 0x12345678(%eax,%ecx,8)",},
635{{0x0f, 0xae, 0x30, }, 3, 0, "", "",
636"0f ae 30 \txsaveopt (%eax)",},
637{{0x0f, 0xae, 0xf0, }, 3, 0, "", "",
638"0f ae f0 \tmfence ",},
639{{0x0f, 0xc7, 0x20, }, 3, 0, "", "",
640"0f c7 20 \txsavec (%eax)",},
641{{0x0f, 0xc7, 0x25, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
642"0f c7 25 78 56 34 12 \txsavec 0x12345678",},
643{{0x0f, 0xc7, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
644"0f c7 a4 c8 78 56 34 12 \txsavec 0x12345678(%eax,%ecx,8)",},
645{{0x0f, 0xc7, 0x28, }, 3, 0, "", "",
646"0f c7 28 \txsaves (%eax)",},
647{{0x0f, 0xc7, 0x2d, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
648"0f c7 2d 78 56 34 12 \txsaves 0x12345678",},
649{{0x0f, 0xc7, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
650"0f c7 ac c8 78 56 34 12 \txsaves 0x12345678(%eax,%ecx,8)",},
651{{0x0f, 0xc7, 0x18, }, 3, 0, "", "",
652"0f c7 18 \txrstors (%eax)",},
653{{0x0f, 0xc7, 0x1d, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
654"0f c7 1d 78 56 34 12 \txrstors 0x12345678",},
655{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
656"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
new file mode 100644
index 000000000000..4fe7cce179c4
--- /dev/null
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-64.c
@@ -0,0 +1,768 @@
1/*
2 * Generated by gen-insn-x86-dat.sh and gen-insn-x86-dat.awk
3 * from insn-x86-dat-src.c for inclusion by insn-x86.c
4 * Do not change this code.
5*/
6
7{{0x0f, 0x31, }, 2, 0, "", "",
8"0f 31 \trdtsc ",},
9{{0xf3, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
10"f3 0f 1b 00 \tbndmk (%rax),%bnd0",},
11{{0xf3, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "",
12"f3 41 0f 1b 00 \tbndmk (%r8),%bnd0",},
13{{0xf3, 0x0f, 0x1b, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
14"f3 0f 1b 04 25 78 56 34 12 \tbndmk 0x12345678,%bnd0",},
15{{0xf3, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
16"f3 0f 1b 18 \tbndmk (%rax),%bnd3",},
17{{0xf3, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
18"f3 0f 1b 04 01 \tbndmk (%rcx,%rax,1),%bnd0",},
19{{0xf3, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
20"f3 0f 1b 04 05 78 56 34 12 \tbndmk 0x12345678(,%rax,1),%bnd0",},
21{{0xf3, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
22"f3 0f 1b 04 08 \tbndmk (%rax,%rcx,1),%bnd0",},
23{{0xf3, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
24"f3 0f 1b 04 c8 \tbndmk (%rax,%rcx,8),%bnd0",},
25{{0xf3, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
26"f3 0f 1b 40 12 \tbndmk 0x12(%rax),%bnd0",},
27{{0xf3, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
28"f3 0f 1b 45 12 \tbndmk 0x12(%rbp),%bnd0",},
29{{0xf3, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
30"f3 0f 1b 44 01 12 \tbndmk 0x12(%rcx,%rax,1),%bnd0",},
31{{0xf3, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
32"f3 0f 1b 44 05 12 \tbndmk 0x12(%rbp,%rax,1),%bnd0",},
33{{0xf3, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
34"f3 0f 1b 44 08 12 \tbndmk 0x12(%rax,%rcx,1),%bnd0",},
35{{0xf3, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
36"f3 0f 1b 44 c8 12 \tbndmk 0x12(%rax,%rcx,8),%bnd0",},
37{{0xf3, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
38"f3 0f 1b 80 78 56 34 12 \tbndmk 0x12345678(%rax),%bnd0",},
39{{0xf3, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
40"f3 0f 1b 85 78 56 34 12 \tbndmk 0x12345678(%rbp),%bnd0",},
41{{0xf3, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
42"f3 0f 1b 84 01 78 56 34 12 \tbndmk 0x12345678(%rcx,%rax,1),%bnd0",},
43{{0xf3, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
44"f3 0f 1b 84 05 78 56 34 12 \tbndmk 0x12345678(%rbp,%rax,1),%bnd0",},
45{{0xf3, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
46"f3 0f 1b 84 08 78 56 34 12 \tbndmk 0x12345678(%rax,%rcx,1),%bnd0",},
47{{0xf3, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
48"f3 0f 1b 84 c8 78 56 34 12 \tbndmk 0x12345678(%rax,%rcx,8),%bnd0",},
49{{0xf3, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
50"f3 0f 1a 00 \tbndcl (%rax),%bnd0",},
51{{0xf3, 0x41, 0x0f, 0x1a, 0x00, }, 5, 0, "", "",
52"f3 41 0f 1a 00 \tbndcl (%r8),%bnd0",},
53{{0xf3, 0x0f, 0x1a, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
54"f3 0f 1a 04 25 78 56 34 12 \tbndcl 0x12345678,%bnd0",},
55{{0xf3, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
56"f3 0f 1a 18 \tbndcl (%rax),%bnd3",},
57{{0xf3, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
58"f3 0f 1a 04 01 \tbndcl (%rcx,%rax,1),%bnd0",},
59{{0xf3, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
60"f3 0f 1a 04 05 78 56 34 12 \tbndcl 0x12345678(,%rax,1),%bnd0",},
61{{0xf3, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
62"f3 0f 1a 04 08 \tbndcl (%rax,%rcx,1),%bnd0",},
63{{0xf3, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
64"f3 0f 1a 04 c8 \tbndcl (%rax,%rcx,8),%bnd0",},
65{{0xf3, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
66"f3 0f 1a 40 12 \tbndcl 0x12(%rax),%bnd0",},
67{{0xf3, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
68"f3 0f 1a 45 12 \tbndcl 0x12(%rbp),%bnd0",},
69{{0xf3, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
70"f3 0f 1a 44 01 12 \tbndcl 0x12(%rcx,%rax,1),%bnd0",},
71{{0xf3, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
72"f3 0f 1a 44 05 12 \tbndcl 0x12(%rbp,%rax,1),%bnd0",},
73{{0xf3, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
74"f3 0f 1a 44 08 12 \tbndcl 0x12(%rax,%rcx,1),%bnd0",},
75{{0xf3, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
76"f3 0f 1a 44 c8 12 \tbndcl 0x12(%rax,%rcx,8),%bnd0",},
77{{0xf3, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
78"f3 0f 1a 80 78 56 34 12 \tbndcl 0x12345678(%rax),%bnd0",},
79{{0xf3, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
80"f3 0f 1a 85 78 56 34 12 \tbndcl 0x12345678(%rbp),%bnd0",},
81{{0xf3, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
82"f3 0f 1a 84 01 78 56 34 12 \tbndcl 0x12345678(%rcx,%rax,1),%bnd0",},
83{{0xf3, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
84"f3 0f 1a 84 05 78 56 34 12 \tbndcl 0x12345678(%rbp,%rax,1),%bnd0",},
85{{0xf3, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
86"f3 0f 1a 84 08 78 56 34 12 \tbndcl 0x12345678(%rax,%rcx,1),%bnd0",},
87{{0xf3, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
88"f3 0f 1a 84 c8 78 56 34 12 \tbndcl 0x12345678(%rax,%rcx,8),%bnd0",},
89{{0xf3, 0x0f, 0x1a, 0xc0, }, 4, 0, "", "",
90"f3 0f 1a c0 \tbndcl %rax,%bnd0",},
91{{0xf2, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
92"f2 0f 1a 00 \tbndcu (%rax),%bnd0",},
93{{0xf2, 0x41, 0x0f, 0x1a, 0x00, }, 5, 0, "", "",
94"f2 41 0f 1a 00 \tbndcu (%r8),%bnd0",},
95{{0xf2, 0x0f, 0x1a, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
96"f2 0f 1a 04 25 78 56 34 12 \tbndcu 0x12345678,%bnd0",},
97{{0xf2, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
98"f2 0f 1a 18 \tbndcu (%rax),%bnd3",},
99{{0xf2, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
100"f2 0f 1a 04 01 \tbndcu (%rcx,%rax,1),%bnd0",},
101{{0xf2, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
102"f2 0f 1a 04 05 78 56 34 12 \tbndcu 0x12345678(,%rax,1),%bnd0",},
103{{0xf2, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
104"f2 0f 1a 04 08 \tbndcu (%rax,%rcx,1),%bnd0",},
105{{0xf2, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
106"f2 0f 1a 04 c8 \tbndcu (%rax,%rcx,8),%bnd0",},
107{{0xf2, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
108"f2 0f 1a 40 12 \tbndcu 0x12(%rax),%bnd0",},
109{{0xf2, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
110"f2 0f 1a 45 12 \tbndcu 0x12(%rbp),%bnd0",},
111{{0xf2, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
112"f2 0f 1a 44 01 12 \tbndcu 0x12(%rcx,%rax,1),%bnd0",},
113{{0xf2, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
114"f2 0f 1a 44 05 12 \tbndcu 0x12(%rbp,%rax,1),%bnd0",},
115{{0xf2, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
116"f2 0f 1a 44 08 12 \tbndcu 0x12(%rax,%rcx,1),%bnd0",},
117{{0xf2, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
118"f2 0f 1a 44 c8 12 \tbndcu 0x12(%rax,%rcx,8),%bnd0",},
119{{0xf2, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
120"f2 0f 1a 80 78 56 34 12 \tbndcu 0x12345678(%rax),%bnd0",},
121{{0xf2, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
122"f2 0f 1a 85 78 56 34 12 \tbndcu 0x12345678(%rbp),%bnd0",},
123{{0xf2, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
124"f2 0f 1a 84 01 78 56 34 12 \tbndcu 0x12345678(%rcx,%rax,1),%bnd0",},
125{{0xf2, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
126"f2 0f 1a 84 05 78 56 34 12 \tbndcu 0x12345678(%rbp,%rax,1),%bnd0",},
127{{0xf2, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
128"f2 0f 1a 84 08 78 56 34 12 \tbndcu 0x12345678(%rax,%rcx,1),%bnd0",},
129{{0xf2, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
130"f2 0f 1a 84 c8 78 56 34 12 \tbndcu 0x12345678(%rax,%rcx,8),%bnd0",},
131{{0xf2, 0x0f, 0x1a, 0xc0, }, 4, 0, "", "",
132"f2 0f 1a c0 \tbndcu %rax,%bnd0",},
133{{0xf2, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
134"f2 0f 1b 00 \tbndcn (%rax),%bnd0",},
135{{0xf2, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "",
136"f2 41 0f 1b 00 \tbndcn (%r8),%bnd0",},
137{{0xf2, 0x0f, 0x1b, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
138"f2 0f 1b 04 25 78 56 34 12 \tbndcn 0x12345678,%bnd0",},
139{{0xf2, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
140"f2 0f 1b 18 \tbndcn (%rax),%bnd3",},
141{{0xf2, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
142"f2 0f 1b 04 01 \tbndcn (%rcx,%rax,1),%bnd0",},
143{{0xf2, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
144"f2 0f 1b 04 05 78 56 34 12 \tbndcn 0x12345678(,%rax,1),%bnd0",},
145{{0xf2, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
146"f2 0f 1b 04 08 \tbndcn (%rax,%rcx,1),%bnd0",},
147{{0xf2, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
148"f2 0f 1b 04 c8 \tbndcn (%rax,%rcx,8),%bnd0",},
149{{0xf2, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
150"f2 0f 1b 40 12 \tbndcn 0x12(%rax),%bnd0",},
151{{0xf2, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
152"f2 0f 1b 45 12 \tbndcn 0x12(%rbp),%bnd0",},
153{{0xf2, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
154"f2 0f 1b 44 01 12 \tbndcn 0x12(%rcx,%rax,1),%bnd0",},
155{{0xf2, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
156"f2 0f 1b 44 05 12 \tbndcn 0x12(%rbp,%rax,1),%bnd0",},
157{{0xf2, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
158"f2 0f 1b 44 08 12 \tbndcn 0x12(%rax,%rcx,1),%bnd0",},
159{{0xf2, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
160"f2 0f 1b 44 c8 12 \tbndcn 0x12(%rax,%rcx,8),%bnd0",},
161{{0xf2, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
162"f2 0f 1b 80 78 56 34 12 \tbndcn 0x12345678(%rax),%bnd0",},
163{{0xf2, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
164"f2 0f 1b 85 78 56 34 12 \tbndcn 0x12345678(%rbp),%bnd0",},
165{{0xf2, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
166"f2 0f 1b 84 01 78 56 34 12 \tbndcn 0x12345678(%rcx,%rax,1),%bnd0",},
167{{0xf2, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
168"f2 0f 1b 84 05 78 56 34 12 \tbndcn 0x12345678(%rbp,%rax,1),%bnd0",},
169{{0xf2, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
170"f2 0f 1b 84 08 78 56 34 12 \tbndcn 0x12345678(%rax,%rcx,1),%bnd0",},
171{{0xf2, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
172"f2 0f 1b 84 c8 78 56 34 12 \tbndcn 0x12345678(%rax,%rcx,8),%bnd0",},
173{{0xf2, 0x0f, 0x1b, 0xc0, }, 4, 0, "", "",
174"f2 0f 1b c0 \tbndcn %rax,%bnd0",},
175{{0x66, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
176"66 0f 1a 00 \tbndmov (%rax),%bnd0",},
177{{0x66, 0x41, 0x0f, 0x1a, 0x00, }, 5, 0, "", "",
178"66 41 0f 1a 00 \tbndmov (%r8),%bnd0",},
179{{0x66, 0x0f, 0x1a, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
180"66 0f 1a 04 25 78 56 34 12 \tbndmov 0x12345678,%bnd0",},
181{{0x66, 0x0f, 0x1a, 0x18, }, 4, 0, "", "",
182"66 0f 1a 18 \tbndmov (%rax),%bnd3",},
183{{0x66, 0x0f, 0x1a, 0x04, 0x01, }, 5, 0, "", "",
184"66 0f 1a 04 01 \tbndmov (%rcx,%rax,1),%bnd0",},
185{{0x66, 0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
186"66 0f 1a 04 05 78 56 34 12 \tbndmov 0x12345678(,%rax,1),%bnd0",},
187{{0x66, 0x0f, 0x1a, 0x04, 0x08, }, 5, 0, "", "",
188"66 0f 1a 04 08 \tbndmov (%rax,%rcx,1),%bnd0",},
189{{0x66, 0x0f, 0x1a, 0x04, 0xc8, }, 5, 0, "", "",
190"66 0f 1a 04 c8 \tbndmov (%rax,%rcx,8),%bnd0",},
191{{0x66, 0x0f, 0x1a, 0x40, 0x12, }, 5, 0, "", "",
192"66 0f 1a 40 12 \tbndmov 0x12(%rax),%bnd0",},
193{{0x66, 0x0f, 0x1a, 0x45, 0x12, }, 5, 0, "", "",
194"66 0f 1a 45 12 \tbndmov 0x12(%rbp),%bnd0",},
195{{0x66, 0x0f, 0x1a, 0x44, 0x01, 0x12, }, 6, 0, "", "",
196"66 0f 1a 44 01 12 \tbndmov 0x12(%rcx,%rax,1),%bnd0",},
197{{0x66, 0x0f, 0x1a, 0x44, 0x05, 0x12, }, 6, 0, "", "",
198"66 0f 1a 44 05 12 \tbndmov 0x12(%rbp,%rax,1),%bnd0",},
199{{0x66, 0x0f, 0x1a, 0x44, 0x08, 0x12, }, 6, 0, "", "",
200"66 0f 1a 44 08 12 \tbndmov 0x12(%rax,%rcx,1),%bnd0",},
201{{0x66, 0x0f, 0x1a, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
202"66 0f 1a 44 c8 12 \tbndmov 0x12(%rax,%rcx,8),%bnd0",},
203{{0x66, 0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
204"66 0f 1a 80 78 56 34 12 \tbndmov 0x12345678(%rax),%bnd0",},
205{{0x66, 0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
206"66 0f 1a 85 78 56 34 12 \tbndmov 0x12345678(%rbp),%bnd0",},
207{{0x66, 0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
208"66 0f 1a 84 01 78 56 34 12 \tbndmov 0x12345678(%rcx,%rax,1),%bnd0",},
209{{0x66, 0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
210"66 0f 1a 84 05 78 56 34 12 \tbndmov 0x12345678(%rbp,%rax,1),%bnd0",},
211{{0x66, 0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
212"66 0f 1a 84 08 78 56 34 12 \tbndmov 0x12345678(%rax,%rcx,1),%bnd0",},
213{{0x66, 0x0f, 0x1a, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
214"66 0f 1a 84 c8 78 56 34 12 \tbndmov 0x12345678(%rax,%rcx,8),%bnd0",},
215{{0x66, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
216"66 0f 1b 00 \tbndmov %bnd0,(%rax)",},
217{{0x66, 0x41, 0x0f, 0x1b, 0x00, }, 5, 0, "", "",
218"66 41 0f 1b 00 \tbndmov %bnd0,(%r8)",},
219{{0x66, 0x0f, 0x1b, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
220"66 0f 1b 04 25 78 56 34 12 \tbndmov %bnd0,0x12345678",},
221{{0x66, 0x0f, 0x1b, 0x18, }, 4, 0, "", "",
222"66 0f 1b 18 \tbndmov %bnd3,(%rax)",},
223{{0x66, 0x0f, 0x1b, 0x04, 0x01, }, 5, 0, "", "",
224"66 0f 1b 04 01 \tbndmov %bnd0,(%rcx,%rax,1)",},
225{{0x66, 0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
226"66 0f 1b 04 05 78 56 34 12 \tbndmov %bnd0,0x12345678(,%rax,1)",},
227{{0x66, 0x0f, 0x1b, 0x04, 0x08, }, 5, 0, "", "",
228"66 0f 1b 04 08 \tbndmov %bnd0,(%rax,%rcx,1)",},
229{{0x66, 0x0f, 0x1b, 0x04, 0xc8, }, 5, 0, "", "",
230"66 0f 1b 04 c8 \tbndmov %bnd0,(%rax,%rcx,8)",},
231{{0x66, 0x0f, 0x1b, 0x40, 0x12, }, 5, 0, "", "",
232"66 0f 1b 40 12 \tbndmov %bnd0,0x12(%rax)",},
233{{0x66, 0x0f, 0x1b, 0x45, 0x12, }, 5, 0, "", "",
234"66 0f 1b 45 12 \tbndmov %bnd0,0x12(%rbp)",},
235{{0x66, 0x0f, 0x1b, 0x44, 0x01, 0x12, }, 6, 0, "", "",
236"66 0f 1b 44 01 12 \tbndmov %bnd0,0x12(%rcx,%rax,1)",},
237{{0x66, 0x0f, 0x1b, 0x44, 0x05, 0x12, }, 6, 0, "", "",
238"66 0f 1b 44 05 12 \tbndmov %bnd0,0x12(%rbp,%rax,1)",},
239{{0x66, 0x0f, 0x1b, 0x44, 0x08, 0x12, }, 6, 0, "", "",
240"66 0f 1b 44 08 12 \tbndmov %bnd0,0x12(%rax,%rcx,1)",},
241{{0x66, 0x0f, 0x1b, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
242"66 0f 1b 44 c8 12 \tbndmov %bnd0,0x12(%rax,%rcx,8)",},
243{{0x66, 0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
244"66 0f 1b 80 78 56 34 12 \tbndmov %bnd0,0x12345678(%rax)",},
245{{0x66, 0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
246"66 0f 1b 85 78 56 34 12 \tbndmov %bnd0,0x12345678(%rbp)",},
247{{0x66, 0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
248"66 0f 1b 84 01 78 56 34 12 \tbndmov %bnd0,0x12345678(%rcx,%rax,1)",},
249{{0x66, 0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
250"66 0f 1b 84 05 78 56 34 12 \tbndmov %bnd0,0x12345678(%rbp,%rax,1)",},
251{{0x66, 0x0f, 0x1b, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
252"66 0f 1b 84 08 78 56 34 12 \tbndmov %bnd0,0x12345678(%rax,%rcx,1)",},
253{{0x66, 0x0f, 0x1b, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
254"66 0f 1b 84 c8 78 56 34 12 \tbndmov %bnd0,0x12345678(%rax,%rcx,8)",},
255{{0x66, 0x0f, 0x1a, 0xc8, }, 4, 0, "", "",
256"66 0f 1a c8 \tbndmov %bnd0,%bnd1",},
257{{0x66, 0x0f, 0x1a, 0xc1, }, 4, 0, "", "",
258"66 0f 1a c1 \tbndmov %bnd1,%bnd0",},
259{{0x0f, 0x1a, 0x00, }, 3, 0, "", "",
260"0f 1a 00 \tbndldx (%rax),%bnd0",},
261{{0x41, 0x0f, 0x1a, 0x00, }, 4, 0, "", "",
262"41 0f 1a 00 \tbndldx (%r8),%bnd0",},
263{{0x0f, 0x1a, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
264"0f 1a 04 25 78 56 34 12 \tbndldx 0x12345678,%bnd0",},
265{{0x0f, 0x1a, 0x18, }, 3, 0, "", "",
266"0f 1a 18 \tbndldx (%rax),%bnd3",},
267{{0x0f, 0x1a, 0x04, 0x01, }, 4, 0, "", "",
268"0f 1a 04 01 \tbndldx (%rcx,%rax,1),%bnd0",},
269{{0x0f, 0x1a, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
270"0f 1a 04 05 78 56 34 12 \tbndldx 0x12345678(,%rax,1),%bnd0",},
271{{0x0f, 0x1a, 0x04, 0x08, }, 4, 0, "", "",
272"0f 1a 04 08 \tbndldx (%rax,%rcx,1),%bnd0",},
273{{0x0f, 0x1a, 0x40, 0x12, }, 4, 0, "", "",
274"0f 1a 40 12 \tbndldx 0x12(%rax),%bnd0",},
275{{0x0f, 0x1a, 0x45, 0x12, }, 4, 0, "", "",
276"0f 1a 45 12 \tbndldx 0x12(%rbp),%bnd0",},
277{{0x0f, 0x1a, 0x44, 0x01, 0x12, }, 5, 0, "", "",
278"0f 1a 44 01 12 \tbndldx 0x12(%rcx,%rax,1),%bnd0",},
279{{0x0f, 0x1a, 0x44, 0x05, 0x12, }, 5, 0, "", "",
280"0f 1a 44 05 12 \tbndldx 0x12(%rbp,%rax,1),%bnd0",},
281{{0x0f, 0x1a, 0x44, 0x08, 0x12, }, 5, 0, "", "",
282"0f 1a 44 08 12 \tbndldx 0x12(%rax,%rcx,1),%bnd0",},
283{{0x0f, 0x1a, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
284"0f 1a 80 78 56 34 12 \tbndldx 0x12345678(%rax),%bnd0",},
285{{0x0f, 0x1a, 0x85, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
286"0f 1a 85 78 56 34 12 \tbndldx 0x12345678(%rbp),%bnd0",},
287{{0x0f, 0x1a, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
288"0f 1a 84 01 78 56 34 12 \tbndldx 0x12345678(%rcx,%rax,1),%bnd0",},
289{{0x0f, 0x1a, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
290"0f 1a 84 05 78 56 34 12 \tbndldx 0x12345678(%rbp,%rax,1),%bnd0",},
291{{0x0f, 0x1a, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
292"0f 1a 84 08 78 56 34 12 \tbndldx 0x12345678(%rax,%rcx,1),%bnd0",},
293{{0x0f, 0x1b, 0x00, }, 3, 0, "", "",
294"0f 1b 00 \tbndstx %bnd0,(%rax)",},
295{{0x41, 0x0f, 0x1b, 0x00, }, 4, 0, "", "",
296"41 0f 1b 00 \tbndstx %bnd0,(%r8)",},
297{{0x0f, 0x1b, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
298"0f 1b 04 25 78 56 34 12 \tbndstx %bnd0,0x12345678",},
299{{0x0f, 0x1b, 0x18, }, 3, 0, "", "",
300"0f 1b 18 \tbndstx %bnd3,(%rax)",},
301{{0x0f, 0x1b, 0x04, 0x01, }, 4, 0, "", "",
302"0f 1b 04 01 \tbndstx %bnd0,(%rcx,%rax,1)",},
303{{0x0f, 0x1b, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
304"0f 1b 04 05 78 56 34 12 \tbndstx %bnd0,0x12345678(,%rax,1)",},
305{{0x0f, 0x1b, 0x04, 0x08, }, 4, 0, "", "",
306"0f 1b 04 08 \tbndstx %bnd0,(%rax,%rcx,1)",},
307{{0x0f, 0x1b, 0x40, 0x12, }, 4, 0, "", "",
308"0f 1b 40 12 \tbndstx %bnd0,0x12(%rax)",},
309{{0x0f, 0x1b, 0x45, 0x12, }, 4, 0, "", "",
310"0f 1b 45 12 \tbndstx %bnd0,0x12(%rbp)",},
311{{0x0f, 0x1b, 0x44, 0x01, 0x12, }, 5, 0, "", "",
312"0f 1b 44 01 12 \tbndstx %bnd0,0x12(%rcx,%rax,1)",},
313{{0x0f, 0x1b, 0x44, 0x05, 0x12, }, 5, 0, "", "",
314"0f 1b 44 05 12 \tbndstx %bnd0,0x12(%rbp,%rax,1)",},
315{{0x0f, 0x1b, 0x44, 0x08, 0x12, }, 5, 0, "", "",
316"0f 1b 44 08 12 \tbndstx %bnd0,0x12(%rax,%rcx,1)",},
317{{0x0f, 0x1b, 0x80, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
318"0f 1b 80 78 56 34 12 \tbndstx %bnd0,0x12345678(%rax)",},
319{{0x0f, 0x1b, 0x85, 0x78, 0x56, 0x34, 0x12, }, 7, 0, "", "",
320"0f 1b 85 78 56 34 12 \tbndstx %bnd0,0x12345678(%rbp)",},
321{{0x0f, 0x1b, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
322"0f 1b 84 01 78 56 34 12 \tbndstx %bnd0,0x12345678(%rcx,%rax,1)",},
323{{0x0f, 0x1b, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
324"0f 1b 84 05 78 56 34 12 \tbndstx %bnd0,0x12345678(%rbp,%rax,1)",},
325{{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)",},
327{{0xf2, 0xe8, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "call", "unconditional",
328"f2 e8 00 00 00 00 \tbnd callq 3f6 <main+0x3f6>",},
329{{0x67, 0xf2, 0xff, 0x10, }, 4, 0, "call", "indirect",
330"67 f2 ff 10 \tbnd callq *(%eax)",},
331{{0xf2, 0xc3, }, 2, 0, "ret", "indirect",
332"f2 c3 \tbnd retq ",},
333{{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional",
334"f2 e9 00 00 00 00 \tbnd jmpq 402 <main+0x402>",},
335{{0xf2, 0xe9, 0x00, 0x00, 0x00, 0x00, }, 6, 0, "jmp", "unconditional",
336"f2 e9 00 00 00 00 \tbnd jmpq 408 <main+0x408>",},
337{{0x67, 0xf2, 0xff, 0x21, }, 4, 0, "jmp", "indirect",
338"67 f2 ff 21 \tbnd jmpq *(%ecx)",},
339{{0xf2, 0x0f, 0x85, 0x00, 0x00, 0x00, 0x00, }, 7, 0, "jcc", "conditional",
340"f2 0f 85 00 00 00 00 \tbnd jne 413 <main+0x413>",},
341{{0x0f, 0x3a, 0xcc, 0xc1, 0x00, }, 5, 0, "", "",
342"0f 3a cc c1 00 \tsha1rnds4 $0x0,%xmm1,%xmm0",},
343{{0x0f, 0x3a, 0xcc, 0xd7, 0x91, }, 5, 0, "", "",
344"0f 3a cc d7 91 \tsha1rnds4 $0x91,%xmm7,%xmm2",},
345{{0x41, 0x0f, 0x3a, 0xcc, 0xc0, 0x91, }, 6, 0, "", "",
346"41 0f 3a cc c0 91 \tsha1rnds4 $0x91,%xmm8,%xmm0",},
347{{0x44, 0x0f, 0x3a, 0xcc, 0xc7, 0x91, }, 6, 0, "", "",
348"44 0f 3a cc c7 91 \tsha1rnds4 $0x91,%xmm7,%xmm8",},
349{{0x45, 0x0f, 0x3a, 0xcc, 0xc7, 0x91, }, 6, 0, "", "",
350"45 0f 3a cc c7 91 \tsha1rnds4 $0x91,%xmm15,%xmm8",},
351{{0x0f, 0x3a, 0xcc, 0x00, 0x91, }, 5, 0, "", "",
352"0f 3a cc 00 91 \tsha1rnds4 $0x91,(%rax),%xmm0",},
353{{0x41, 0x0f, 0x3a, 0xcc, 0x00, 0x91, }, 6, 0, "", "",
354"41 0f 3a cc 00 91 \tsha1rnds4 $0x91,(%r8),%xmm0",},
355{{0x0f, 0x3a, 0xcc, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
356"0f 3a cc 04 25 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678,%xmm0",},
357{{0x0f, 0x3a, 0xcc, 0x18, 0x91, }, 5, 0, "", "",
358"0f 3a cc 18 91 \tsha1rnds4 $0x91,(%rax),%xmm3",},
359{{0x0f, 0x3a, 0xcc, 0x04, 0x01, 0x91, }, 6, 0, "", "",
360"0f 3a cc 04 01 91 \tsha1rnds4 $0x91,(%rcx,%rax,1),%xmm0",},
361{{0x0f, 0x3a, 0xcc, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
362"0f 3a cc 04 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(,%rax,1),%xmm0",},
363{{0x0f, 0x3a, 0xcc, 0x04, 0x08, 0x91, }, 6, 0, "", "",
364"0f 3a cc 04 08 91 \tsha1rnds4 $0x91,(%rax,%rcx,1),%xmm0",},
365{{0x0f, 0x3a, 0xcc, 0x04, 0xc8, 0x91, }, 6, 0, "", "",
366"0f 3a cc 04 c8 91 \tsha1rnds4 $0x91,(%rax,%rcx,8),%xmm0",},
367{{0x0f, 0x3a, 0xcc, 0x40, 0x12, 0x91, }, 6, 0, "", "",
368"0f 3a cc 40 12 91 \tsha1rnds4 $0x91,0x12(%rax),%xmm0",},
369{{0x0f, 0x3a, 0xcc, 0x45, 0x12, 0x91, }, 6, 0, "", "",
370"0f 3a cc 45 12 91 \tsha1rnds4 $0x91,0x12(%rbp),%xmm0",},
371{{0x0f, 0x3a, 0xcc, 0x44, 0x01, 0x12, 0x91, }, 7, 0, "", "",
372"0f 3a cc 44 01 12 91 \tsha1rnds4 $0x91,0x12(%rcx,%rax,1),%xmm0",},
373{{0x0f, 0x3a, 0xcc, 0x44, 0x05, 0x12, 0x91, }, 7, 0, "", "",
374"0f 3a cc 44 05 12 91 \tsha1rnds4 $0x91,0x12(%rbp,%rax,1),%xmm0",},
375{{0x0f, 0x3a, 0xcc, 0x44, 0x08, 0x12, 0x91, }, 7, 0, "", "",
376"0f 3a cc 44 08 12 91 \tsha1rnds4 $0x91,0x12(%rax,%rcx,1),%xmm0",},
377{{0x0f, 0x3a, 0xcc, 0x44, 0xc8, 0x12, 0x91, }, 7, 0, "", "",
378"0f 3a cc 44 c8 12 91 \tsha1rnds4 $0x91,0x12(%rax,%rcx,8),%xmm0",},
379{{0x0f, 0x3a, 0xcc, 0x80, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
380"0f 3a cc 80 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rax),%xmm0",},
381{{0x0f, 0x3a, 0xcc, 0x85, 0x78, 0x56, 0x34, 0x12, 0x91, }, 9, 0, "", "",
382"0f 3a cc 85 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rbp),%xmm0",},
383{{0x0f, 0x3a, 0xcc, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
384"0f 3a cc 84 01 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rcx,%rax,1),%xmm0",},
385{{0x0f, 0x3a, 0xcc, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
386"0f 3a cc 84 05 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rbp,%rax,1),%xmm0",},
387{{0x0f, 0x3a, 0xcc, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
388"0f 3a cc 84 08 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rax,%rcx,1),%xmm0",},
389{{0x0f, 0x3a, 0xcc, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x91, }, 10, 0, "", "",
390"0f 3a cc 84 c8 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rax,%rcx,8),%xmm0",},
391{{0x44, 0x0f, 0x3a, 0xcc, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, 0x91, }, 11, 0, "", "",
392"44 0f 3a cc bc c8 78 56 34 12 91 \tsha1rnds4 $0x91,0x12345678(%rax,%rcx,8),%xmm15",},
393{{0x0f, 0x38, 0xc8, 0xc1, }, 4, 0, "", "",
394"0f 38 c8 c1 \tsha1nexte %xmm1,%xmm0",},
395{{0x0f, 0x38, 0xc8, 0xd7, }, 4, 0, "", "",
396"0f 38 c8 d7 \tsha1nexte %xmm7,%xmm2",},
397{{0x41, 0x0f, 0x38, 0xc8, 0xc0, }, 5, 0, "", "",
398"41 0f 38 c8 c0 \tsha1nexte %xmm8,%xmm0",},
399{{0x44, 0x0f, 0x38, 0xc8, 0xc7, }, 5, 0, "", "",
400"44 0f 38 c8 c7 \tsha1nexte %xmm7,%xmm8",},
401{{0x45, 0x0f, 0x38, 0xc8, 0xc7, }, 5, 0, "", "",
402"45 0f 38 c8 c7 \tsha1nexte %xmm15,%xmm8",},
403{{0x0f, 0x38, 0xc8, 0x00, }, 4, 0, "", "",
404"0f 38 c8 00 \tsha1nexte (%rax),%xmm0",},
405{{0x41, 0x0f, 0x38, 0xc8, 0x00, }, 5, 0, "", "",
406"41 0f 38 c8 00 \tsha1nexte (%r8),%xmm0",},
407{{0x0f, 0x38, 0xc8, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
408"0f 38 c8 04 25 78 56 34 12 \tsha1nexte 0x12345678,%xmm0",},
409{{0x0f, 0x38, 0xc8, 0x18, }, 4, 0, "", "",
410"0f 38 c8 18 \tsha1nexte (%rax),%xmm3",},
411{{0x0f, 0x38, 0xc8, 0x04, 0x01, }, 5, 0, "", "",
412"0f 38 c8 04 01 \tsha1nexte (%rcx,%rax,1),%xmm0",},
413{{0x0f, 0x38, 0xc8, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
414"0f 38 c8 04 05 78 56 34 12 \tsha1nexte 0x12345678(,%rax,1),%xmm0",},
415{{0x0f, 0x38, 0xc8, 0x04, 0x08, }, 5, 0, "", "",
416"0f 38 c8 04 08 \tsha1nexte (%rax,%rcx,1),%xmm0",},
417{{0x0f, 0x38, 0xc8, 0x04, 0xc8, }, 5, 0, "", "",
418"0f 38 c8 04 c8 \tsha1nexte (%rax,%rcx,8),%xmm0",},
419{{0x0f, 0x38, 0xc8, 0x40, 0x12, }, 5, 0, "", "",
420"0f 38 c8 40 12 \tsha1nexte 0x12(%rax),%xmm0",},
421{{0x0f, 0x38, 0xc8, 0x45, 0x12, }, 5, 0, "", "",
422"0f 38 c8 45 12 \tsha1nexte 0x12(%rbp),%xmm0",},
423{{0x0f, 0x38, 0xc8, 0x44, 0x01, 0x12, }, 6, 0, "", "",
424"0f 38 c8 44 01 12 \tsha1nexte 0x12(%rcx,%rax,1),%xmm0",},
425{{0x0f, 0x38, 0xc8, 0x44, 0x05, 0x12, }, 6, 0, "", "",
426"0f 38 c8 44 05 12 \tsha1nexte 0x12(%rbp,%rax,1),%xmm0",},
427{{0x0f, 0x38, 0xc8, 0x44, 0x08, 0x12, }, 6, 0, "", "",
428"0f 38 c8 44 08 12 \tsha1nexte 0x12(%rax,%rcx,1),%xmm0",},
429{{0x0f, 0x38, 0xc8, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
430"0f 38 c8 44 c8 12 \tsha1nexte 0x12(%rax,%rcx,8),%xmm0",},
431{{0x0f, 0x38, 0xc8, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
432"0f 38 c8 80 78 56 34 12 \tsha1nexte 0x12345678(%rax),%xmm0",},
433{{0x0f, 0x38, 0xc8, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
434"0f 38 c8 85 78 56 34 12 \tsha1nexte 0x12345678(%rbp),%xmm0",},
435{{0x0f, 0x38, 0xc8, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
436"0f 38 c8 84 01 78 56 34 12 \tsha1nexte 0x12345678(%rcx,%rax,1),%xmm0",},
437{{0x0f, 0x38, 0xc8, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
438"0f 38 c8 84 05 78 56 34 12 \tsha1nexte 0x12345678(%rbp,%rax,1),%xmm0",},
439{{0x0f, 0x38, 0xc8, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
440"0f 38 c8 84 08 78 56 34 12 \tsha1nexte 0x12345678(%rax,%rcx,1),%xmm0",},
441{{0x0f, 0x38, 0xc8, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
442"0f 38 c8 84 c8 78 56 34 12 \tsha1nexte 0x12345678(%rax,%rcx,8),%xmm0",},
443{{0x44, 0x0f, 0x38, 0xc8, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
444"44 0f 38 c8 bc c8 78 56 34 12 \tsha1nexte 0x12345678(%rax,%rcx,8),%xmm15",},
445{{0x0f, 0x38, 0xc9, 0xc1, }, 4, 0, "", "",
446"0f 38 c9 c1 \tsha1msg1 %xmm1,%xmm0",},
447{{0x0f, 0x38, 0xc9, 0xd7, }, 4, 0, "", "",
448"0f 38 c9 d7 \tsha1msg1 %xmm7,%xmm2",},
449{{0x41, 0x0f, 0x38, 0xc9, 0xc0, }, 5, 0, "", "",
450"41 0f 38 c9 c0 \tsha1msg1 %xmm8,%xmm0",},
451{{0x44, 0x0f, 0x38, 0xc9, 0xc7, }, 5, 0, "", "",
452"44 0f 38 c9 c7 \tsha1msg1 %xmm7,%xmm8",},
453{{0x45, 0x0f, 0x38, 0xc9, 0xc7, }, 5, 0, "", "",
454"45 0f 38 c9 c7 \tsha1msg1 %xmm15,%xmm8",},
455{{0x0f, 0x38, 0xc9, 0x00, }, 4, 0, "", "",
456"0f 38 c9 00 \tsha1msg1 (%rax),%xmm0",},
457{{0x41, 0x0f, 0x38, 0xc9, 0x00, }, 5, 0, "", "",
458"41 0f 38 c9 00 \tsha1msg1 (%r8),%xmm0",},
459{{0x0f, 0x38, 0xc9, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
460"0f 38 c9 04 25 78 56 34 12 \tsha1msg1 0x12345678,%xmm0",},
461{{0x0f, 0x38, 0xc9, 0x18, }, 4, 0, "", "",
462"0f 38 c9 18 \tsha1msg1 (%rax),%xmm3",},
463{{0x0f, 0x38, 0xc9, 0x04, 0x01, }, 5, 0, "", "",
464"0f 38 c9 04 01 \tsha1msg1 (%rcx,%rax,1),%xmm0",},
465{{0x0f, 0x38, 0xc9, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
466"0f 38 c9 04 05 78 56 34 12 \tsha1msg1 0x12345678(,%rax,1),%xmm0",},
467{{0x0f, 0x38, 0xc9, 0x04, 0x08, }, 5, 0, "", "",
468"0f 38 c9 04 08 \tsha1msg1 (%rax,%rcx,1),%xmm0",},
469{{0x0f, 0x38, 0xc9, 0x04, 0xc8, }, 5, 0, "", "",
470"0f 38 c9 04 c8 \tsha1msg1 (%rax,%rcx,8),%xmm0",},
471{{0x0f, 0x38, 0xc9, 0x40, 0x12, }, 5, 0, "", "",
472"0f 38 c9 40 12 \tsha1msg1 0x12(%rax),%xmm0",},
473{{0x0f, 0x38, 0xc9, 0x45, 0x12, }, 5, 0, "", "",
474"0f 38 c9 45 12 \tsha1msg1 0x12(%rbp),%xmm0",},
475{{0x0f, 0x38, 0xc9, 0x44, 0x01, 0x12, }, 6, 0, "", "",
476"0f 38 c9 44 01 12 \tsha1msg1 0x12(%rcx,%rax,1),%xmm0",},
477{{0x0f, 0x38, 0xc9, 0x44, 0x05, 0x12, }, 6, 0, "", "",
478"0f 38 c9 44 05 12 \tsha1msg1 0x12(%rbp,%rax,1),%xmm0",},
479{{0x0f, 0x38, 0xc9, 0x44, 0x08, 0x12, }, 6, 0, "", "",
480"0f 38 c9 44 08 12 \tsha1msg1 0x12(%rax,%rcx,1),%xmm0",},
481{{0x0f, 0x38, 0xc9, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
482"0f 38 c9 44 c8 12 \tsha1msg1 0x12(%rax,%rcx,8),%xmm0",},
483{{0x0f, 0x38, 0xc9, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
484"0f 38 c9 80 78 56 34 12 \tsha1msg1 0x12345678(%rax),%xmm0",},
485{{0x0f, 0x38, 0xc9, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
486"0f 38 c9 85 78 56 34 12 \tsha1msg1 0x12345678(%rbp),%xmm0",},
487{{0x0f, 0x38, 0xc9, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
488"0f 38 c9 84 01 78 56 34 12 \tsha1msg1 0x12345678(%rcx,%rax,1),%xmm0",},
489{{0x0f, 0x38, 0xc9, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
490"0f 38 c9 84 05 78 56 34 12 \tsha1msg1 0x12345678(%rbp,%rax,1),%xmm0",},
491{{0x0f, 0x38, 0xc9, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
492"0f 38 c9 84 08 78 56 34 12 \tsha1msg1 0x12345678(%rax,%rcx,1),%xmm0",},
493{{0x0f, 0x38, 0xc9, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
494"0f 38 c9 84 c8 78 56 34 12 \tsha1msg1 0x12345678(%rax,%rcx,8),%xmm0",},
495{{0x44, 0x0f, 0x38, 0xc9, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
496"44 0f 38 c9 bc c8 78 56 34 12 \tsha1msg1 0x12345678(%rax,%rcx,8),%xmm15",},
497{{0x0f, 0x38, 0xca, 0xc1, }, 4, 0, "", "",
498"0f 38 ca c1 \tsha1msg2 %xmm1,%xmm0",},
499{{0x0f, 0x38, 0xca, 0xd7, }, 4, 0, "", "",
500"0f 38 ca d7 \tsha1msg2 %xmm7,%xmm2",},
501{{0x41, 0x0f, 0x38, 0xca, 0xc0, }, 5, 0, "", "",
502"41 0f 38 ca c0 \tsha1msg2 %xmm8,%xmm0",},
503{{0x44, 0x0f, 0x38, 0xca, 0xc7, }, 5, 0, "", "",
504"44 0f 38 ca c7 \tsha1msg2 %xmm7,%xmm8",},
505{{0x45, 0x0f, 0x38, 0xca, 0xc7, }, 5, 0, "", "",
506"45 0f 38 ca c7 \tsha1msg2 %xmm15,%xmm8",},
507{{0x0f, 0x38, 0xca, 0x00, }, 4, 0, "", "",
508"0f 38 ca 00 \tsha1msg2 (%rax),%xmm0",},
509{{0x41, 0x0f, 0x38, 0xca, 0x00, }, 5, 0, "", "",
510"41 0f 38 ca 00 \tsha1msg2 (%r8),%xmm0",},
511{{0x0f, 0x38, 0xca, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
512"0f 38 ca 04 25 78 56 34 12 \tsha1msg2 0x12345678,%xmm0",},
513{{0x0f, 0x38, 0xca, 0x18, }, 4, 0, "", "",
514"0f 38 ca 18 \tsha1msg2 (%rax),%xmm3",},
515{{0x0f, 0x38, 0xca, 0x04, 0x01, }, 5, 0, "", "",
516"0f 38 ca 04 01 \tsha1msg2 (%rcx,%rax,1),%xmm0",},
517{{0x0f, 0x38, 0xca, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
518"0f 38 ca 04 05 78 56 34 12 \tsha1msg2 0x12345678(,%rax,1),%xmm0",},
519{{0x0f, 0x38, 0xca, 0x04, 0x08, }, 5, 0, "", "",
520"0f 38 ca 04 08 \tsha1msg2 (%rax,%rcx,1),%xmm0",},
521{{0x0f, 0x38, 0xca, 0x04, 0xc8, }, 5, 0, "", "",
522"0f 38 ca 04 c8 \tsha1msg2 (%rax,%rcx,8),%xmm0",},
523{{0x0f, 0x38, 0xca, 0x40, 0x12, }, 5, 0, "", "",
524"0f 38 ca 40 12 \tsha1msg2 0x12(%rax),%xmm0",},
525{{0x0f, 0x38, 0xca, 0x45, 0x12, }, 5, 0, "", "",
526"0f 38 ca 45 12 \tsha1msg2 0x12(%rbp),%xmm0",},
527{{0x0f, 0x38, 0xca, 0x44, 0x01, 0x12, }, 6, 0, "", "",
528"0f 38 ca 44 01 12 \tsha1msg2 0x12(%rcx,%rax,1),%xmm0",},
529{{0x0f, 0x38, 0xca, 0x44, 0x05, 0x12, }, 6, 0, "", "",
530"0f 38 ca 44 05 12 \tsha1msg2 0x12(%rbp,%rax,1),%xmm0",},
531{{0x0f, 0x38, 0xca, 0x44, 0x08, 0x12, }, 6, 0, "", "",
532"0f 38 ca 44 08 12 \tsha1msg2 0x12(%rax,%rcx,1),%xmm0",},
533{{0x0f, 0x38, 0xca, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
534"0f 38 ca 44 c8 12 \tsha1msg2 0x12(%rax,%rcx,8),%xmm0",},
535{{0x0f, 0x38, 0xca, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
536"0f 38 ca 80 78 56 34 12 \tsha1msg2 0x12345678(%rax),%xmm0",},
537{{0x0f, 0x38, 0xca, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
538"0f 38 ca 85 78 56 34 12 \tsha1msg2 0x12345678(%rbp),%xmm0",},
539{{0x0f, 0x38, 0xca, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
540"0f 38 ca 84 01 78 56 34 12 \tsha1msg2 0x12345678(%rcx,%rax,1),%xmm0",},
541{{0x0f, 0x38, 0xca, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
542"0f 38 ca 84 05 78 56 34 12 \tsha1msg2 0x12345678(%rbp,%rax,1),%xmm0",},
543{{0x0f, 0x38, 0xca, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
544"0f 38 ca 84 08 78 56 34 12 \tsha1msg2 0x12345678(%rax,%rcx,1),%xmm0",},
545{{0x0f, 0x38, 0xca, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
546"0f 38 ca 84 c8 78 56 34 12 \tsha1msg2 0x12345678(%rax,%rcx,8),%xmm0",},
547{{0x44, 0x0f, 0x38, 0xca, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
548"44 0f 38 ca bc c8 78 56 34 12 \tsha1msg2 0x12345678(%rax,%rcx,8),%xmm15",},
549{{0x0f, 0x38, 0xcb, 0xcc, }, 4, 0, "", "",
550"0f 38 cb cc \tsha256rnds2 %xmm0,%xmm4,%xmm1",},
551{{0x0f, 0x38, 0xcb, 0xd7, }, 4, 0, "", "",
552"0f 38 cb d7 \tsha256rnds2 %xmm0,%xmm7,%xmm2",},
553{{0x41, 0x0f, 0x38, 0xcb, 0xc8, }, 5, 0, "", "",
554"41 0f 38 cb c8 \tsha256rnds2 %xmm0,%xmm8,%xmm1",},
555{{0x44, 0x0f, 0x38, 0xcb, 0xc7, }, 5, 0, "", "",
556"44 0f 38 cb c7 \tsha256rnds2 %xmm0,%xmm7,%xmm8",},
557{{0x45, 0x0f, 0x38, 0xcb, 0xc7, }, 5, 0, "", "",
558"45 0f 38 cb c7 \tsha256rnds2 %xmm0,%xmm15,%xmm8",},
559{{0x0f, 0x38, 0xcb, 0x08, }, 4, 0, "", "",
560"0f 38 cb 08 \tsha256rnds2 %xmm0,(%rax),%xmm1",},
561{{0x41, 0x0f, 0x38, 0xcb, 0x08, }, 5, 0, "", "",
562"41 0f 38 cb 08 \tsha256rnds2 %xmm0,(%r8),%xmm1",},
563{{0x0f, 0x38, 0xcb, 0x0c, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
564"0f 38 cb 0c 25 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678,%xmm1",},
565{{0x0f, 0x38, 0xcb, 0x18, }, 4, 0, "", "",
566"0f 38 cb 18 \tsha256rnds2 %xmm0,(%rax),%xmm3",},
567{{0x0f, 0x38, 0xcb, 0x0c, 0x01, }, 5, 0, "", "",
568"0f 38 cb 0c 01 \tsha256rnds2 %xmm0,(%rcx,%rax,1),%xmm1",},
569{{0x0f, 0x38, 0xcb, 0x0c, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
570"0f 38 cb 0c 05 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(,%rax,1),%xmm1",},
571{{0x0f, 0x38, 0xcb, 0x0c, 0x08, }, 5, 0, "", "",
572"0f 38 cb 0c 08 \tsha256rnds2 %xmm0,(%rax,%rcx,1),%xmm1",},
573{{0x0f, 0x38, 0xcb, 0x0c, 0xc8, }, 5, 0, "", "",
574"0f 38 cb 0c c8 \tsha256rnds2 %xmm0,(%rax,%rcx,8),%xmm1",},
575{{0x0f, 0x38, 0xcb, 0x48, 0x12, }, 5, 0, "", "",
576"0f 38 cb 48 12 \tsha256rnds2 %xmm0,0x12(%rax),%xmm1",},
577{{0x0f, 0x38, 0xcb, 0x4d, 0x12, }, 5, 0, "", "",
578"0f 38 cb 4d 12 \tsha256rnds2 %xmm0,0x12(%rbp),%xmm1",},
579{{0x0f, 0x38, 0xcb, 0x4c, 0x01, 0x12, }, 6, 0, "", "",
580"0f 38 cb 4c 01 12 \tsha256rnds2 %xmm0,0x12(%rcx,%rax,1),%xmm1",},
581{{0x0f, 0x38, 0xcb, 0x4c, 0x05, 0x12, }, 6, 0, "", "",
582"0f 38 cb 4c 05 12 \tsha256rnds2 %xmm0,0x12(%rbp,%rax,1),%xmm1",},
583{{0x0f, 0x38, 0xcb, 0x4c, 0x08, 0x12, }, 6, 0, "", "",
584"0f 38 cb 4c 08 12 \tsha256rnds2 %xmm0,0x12(%rax,%rcx,1),%xmm1",},
585{{0x0f, 0x38, 0xcb, 0x4c, 0xc8, 0x12, }, 6, 0, "", "",
586"0f 38 cb 4c c8 12 \tsha256rnds2 %xmm0,0x12(%rax,%rcx,8),%xmm1",},
587{{0x0f, 0x38, 0xcb, 0x88, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
588"0f 38 cb 88 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rax),%xmm1",},
589{{0x0f, 0x38, 0xcb, 0x8d, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
590"0f 38 cb 8d 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rbp),%xmm1",},
591{{0x0f, 0x38, 0xcb, 0x8c, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
592"0f 38 cb 8c 01 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rcx,%rax,1),%xmm1",},
593{{0x0f, 0x38, 0xcb, 0x8c, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
594"0f 38 cb 8c 05 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rbp,%rax,1),%xmm1",},
595{{0x0f, 0x38, 0xcb, 0x8c, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
596"0f 38 cb 8c 08 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rax,%rcx,1),%xmm1",},
597{{0x0f, 0x38, 0xcb, 0x8c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
598"0f 38 cb 8c c8 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rax,%rcx,8),%xmm1",},
599{{0x44, 0x0f, 0x38, 0xcb, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
600"44 0f 38 cb bc c8 78 56 34 12 \tsha256rnds2 %xmm0,0x12345678(%rax,%rcx,8),%xmm15",},
601{{0x0f, 0x38, 0xcc, 0xc1, }, 4, 0, "", "",
602"0f 38 cc c1 \tsha256msg1 %xmm1,%xmm0",},
603{{0x0f, 0x38, 0xcc, 0xd7, }, 4, 0, "", "",
604"0f 38 cc d7 \tsha256msg1 %xmm7,%xmm2",},
605{{0x41, 0x0f, 0x38, 0xcc, 0xc0, }, 5, 0, "", "",
606"41 0f 38 cc c0 \tsha256msg1 %xmm8,%xmm0",},
607{{0x44, 0x0f, 0x38, 0xcc, 0xc7, }, 5, 0, "", "",
608"44 0f 38 cc c7 \tsha256msg1 %xmm7,%xmm8",},
609{{0x45, 0x0f, 0x38, 0xcc, 0xc7, }, 5, 0, "", "",
610"45 0f 38 cc c7 \tsha256msg1 %xmm15,%xmm8",},
611{{0x0f, 0x38, 0xcc, 0x00, }, 4, 0, "", "",
612"0f 38 cc 00 \tsha256msg1 (%rax),%xmm0",},
613{{0x41, 0x0f, 0x38, 0xcc, 0x00, }, 5, 0, "", "",
614"41 0f 38 cc 00 \tsha256msg1 (%r8),%xmm0",},
615{{0x0f, 0x38, 0xcc, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
616"0f 38 cc 04 25 78 56 34 12 \tsha256msg1 0x12345678,%xmm0",},
617{{0x0f, 0x38, 0xcc, 0x18, }, 4, 0, "", "",
618"0f 38 cc 18 \tsha256msg1 (%rax),%xmm3",},
619{{0x0f, 0x38, 0xcc, 0x04, 0x01, }, 5, 0, "", "",
620"0f 38 cc 04 01 \tsha256msg1 (%rcx,%rax,1),%xmm0",},
621{{0x0f, 0x38, 0xcc, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
622"0f 38 cc 04 05 78 56 34 12 \tsha256msg1 0x12345678(,%rax,1),%xmm0",},
623{{0x0f, 0x38, 0xcc, 0x04, 0x08, }, 5, 0, "", "",
624"0f 38 cc 04 08 \tsha256msg1 (%rax,%rcx,1),%xmm0",},
625{{0x0f, 0x38, 0xcc, 0x04, 0xc8, }, 5, 0, "", "",
626"0f 38 cc 04 c8 \tsha256msg1 (%rax,%rcx,8),%xmm0",},
627{{0x0f, 0x38, 0xcc, 0x40, 0x12, }, 5, 0, "", "",
628"0f 38 cc 40 12 \tsha256msg1 0x12(%rax),%xmm0",},
629{{0x0f, 0x38, 0xcc, 0x45, 0x12, }, 5, 0, "", "",
630"0f 38 cc 45 12 \tsha256msg1 0x12(%rbp),%xmm0",},
631{{0x0f, 0x38, 0xcc, 0x44, 0x01, 0x12, }, 6, 0, "", "",
632"0f 38 cc 44 01 12 \tsha256msg1 0x12(%rcx,%rax,1),%xmm0",},
633{{0x0f, 0x38, 0xcc, 0x44, 0x05, 0x12, }, 6, 0, "", "",
634"0f 38 cc 44 05 12 \tsha256msg1 0x12(%rbp,%rax,1),%xmm0",},
635{{0x0f, 0x38, 0xcc, 0x44, 0x08, 0x12, }, 6, 0, "", "",
636"0f 38 cc 44 08 12 \tsha256msg1 0x12(%rax,%rcx,1),%xmm0",},
637{{0x0f, 0x38, 0xcc, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
638"0f 38 cc 44 c8 12 \tsha256msg1 0x12(%rax,%rcx,8),%xmm0",},
639{{0x0f, 0x38, 0xcc, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
640"0f 38 cc 80 78 56 34 12 \tsha256msg1 0x12345678(%rax),%xmm0",},
641{{0x0f, 0x38, 0xcc, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
642"0f 38 cc 85 78 56 34 12 \tsha256msg1 0x12345678(%rbp),%xmm0",},
643{{0x0f, 0x38, 0xcc, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
644"0f 38 cc 84 01 78 56 34 12 \tsha256msg1 0x12345678(%rcx,%rax,1),%xmm0",},
645{{0x0f, 0x38, 0xcc, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
646"0f 38 cc 84 05 78 56 34 12 \tsha256msg1 0x12345678(%rbp,%rax,1),%xmm0",},
647{{0x0f, 0x38, 0xcc, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
648"0f 38 cc 84 08 78 56 34 12 \tsha256msg1 0x12345678(%rax,%rcx,1),%xmm0",},
649{{0x0f, 0x38, 0xcc, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
650"0f 38 cc 84 c8 78 56 34 12 \tsha256msg1 0x12345678(%rax,%rcx,8),%xmm0",},
651{{0x44, 0x0f, 0x38, 0xcc, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
652"44 0f 38 cc bc c8 78 56 34 12 \tsha256msg1 0x12345678(%rax,%rcx,8),%xmm15",},
653{{0x0f, 0x38, 0xcd, 0xc1, }, 4, 0, "", "",
654"0f 38 cd c1 \tsha256msg2 %xmm1,%xmm0",},
655{{0x0f, 0x38, 0xcd, 0xd7, }, 4, 0, "", "",
656"0f 38 cd d7 \tsha256msg2 %xmm7,%xmm2",},
657{{0x41, 0x0f, 0x38, 0xcd, 0xc0, }, 5, 0, "", "",
658"41 0f 38 cd c0 \tsha256msg2 %xmm8,%xmm0",},
659{{0x44, 0x0f, 0x38, 0xcd, 0xc7, }, 5, 0, "", "",
660"44 0f 38 cd c7 \tsha256msg2 %xmm7,%xmm8",},
661{{0x45, 0x0f, 0x38, 0xcd, 0xc7, }, 5, 0, "", "",
662"45 0f 38 cd c7 \tsha256msg2 %xmm15,%xmm8",},
663{{0x0f, 0x38, 0xcd, 0x00, }, 4, 0, "", "",
664"0f 38 cd 00 \tsha256msg2 (%rax),%xmm0",},
665{{0x41, 0x0f, 0x38, 0xcd, 0x00, }, 5, 0, "", "",
666"41 0f 38 cd 00 \tsha256msg2 (%r8),%xmm0",},
667{{0x0f, 0x38, 0xcd, 0x04, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
668"0f 38 cd 04 25 78 56 34 12 \tsha256msg2 0x12345678,%xmm0",},
669{{0x0f, 0x38, 0xcd, 0x18, }, 4, 0, "", "",
670"0f 38 cd 18 \tsha256msg2 (%rax),%xmm3",},
671{{0x0f, 0x38, 0xcd, 0x04, 0x01, }, 5, 0, "", "",
672"0f 38 cd 04 01 \tsha256msg2 (%rcx,%rax,1),%xmm0",},
673{{0x0f, 0x38, 0xcd, 0x04, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
674"0f 38 cd 04 05 78 56 34 12 \tsha256msg2 0x12345678(,%rax,1),%xmm0",},
675{{0x0f, 0x38, 0xcd, 0x04, 0x08, }, 5, 0, "", "",
676"0f 38 cd 04 08 \tsha256msg2 (%rax,%rcx,1),%xmm0",},
677{{0x0f, 0x38, 0xcd, 0x04, 0xc8, }, 5, 0, "", "",
678"0f 38 cd 04 c8 \tsha256msg2 (%rax,%rcx,8),%xmm0",},
679{{0x0f, 0x38, 0xcd, 0x40, 0x12, }, 5, 0, "", "",
680"0f 38 cd 40 12 \tsha256msg2 0x12(%rax),%xmm0",},
681{{0x0f, 0x38, 0xcd, 0x45, 0x12, }, 5, 0, "", "",
682"0f 38 cd 45 12 \tsha256msg2 0x12(%rbp),%xmm0",},
683{{0x0f, 0x38, 0xcd, 0x44, 0x01, 0x12, }, 6, 0, "", "",
684"0f 38 cd 44 01 12 \tsha256msg2 0x12(%rcx,%rax,1),%xmm0",},
685{{0x0f, 0x38, 0xcd, 0x44, 0x05, 0x12, }, 6, 0, "", "",
686"0f 38 cd 44 05 12 \tsha256msg2 0x12(%rbp,%rax,1),%xmm0",},
687{{0x0f, 0x38, 0xcd, 0x44, 0x08, 0x12, }, 6, 0, "", "",
688"0f 38 cd 44 08 12 \tsha256msg2 0x12(%rax,%rcx,1),%xmm0",},
689{{0x0f, 0x38, 0xcd, 0x44, 0xc8, 0x12, }, 6, 0, "", "",
690"0f 38 cd 44 c8 12 \tsha256msg2 0x12(%rax,%rcx,8),%xmm0",},
691{{0x0f, 0x38, 0xcd, 0x80, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
692"0f 38 cd 80 78 56 34 12 \tsha256msg2 0x12345678(%rax),%xmm0",},
693{{0x0f, 0x38, 0xcd, 0x85, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
694"0f 38 cd 85 78 56 34 12 \tsha256msg2 0x12345678(%rbp),%xmm0",},
695{{0x0f, 0x38, 0xcd, 0x84, 0x01, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
696"0f 38 cd 84 01 78 56 34 12 \tsha256msg2 0x12345678(%rcx,%rax,1),%xmm0",},
697{{0x0f, 0x38, 0xcd, 0x84, 0x05, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
698"0f 38 cd 84 05 78 56 34 12 \tsha256msg2 0x12345678(%rbp,%rax,1),%xmm0",},
699{{0x0f, 0x38, 0xcd, 0x84, 0x08, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
700"0f 38 cd 84 08 78 56 34 12 \tsha256msg2 0x12345678(%rax,%rcx,1),%xmm0",},
701{{0x0f, 0x38, 0xcd, 0x84, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
702"0f 38 cd 84 c8 78 56 34 12 \tsha256msg2 0x12345678(%rax,%rcx,8),%xmm0",},
703{{0x44, 0x0f, 0x38, 0xcd, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
704"44 0f 38 cd bc c8 78 56 34 12 \tsha256msg2 0x12345678(%rax,%rcx,8),%xmm15",},
705{{0x66, 0x0f, 0xae, 0x38, }, 4, 0, "", "",
706"66 0f ae 38 \tclflushopt (%rax)",},
707{{0x66, 0x41, 0x0f, 0xae, 0x38, }, 5, 0, "", "",
708"66 41 0f ae 38 \tclflushopt (%r8)",},
709{{0x66, 0x0f, 0xae, 0x3c, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
710"66 0f ae 3c 25 78 56 34 12 \tclflushopt 0x12345678",},
711{{0x66, 0x0f, 0xae, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
712"66 0f ae bc c8 78 56 34 12 \tclflushopt 0x12345678(%rax,%rcx,8)",},
713{{0x66, 0x41, 0x0f, 0xae, 0xbc, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
714"66 41 0f ae bc c8 78 56 34 12 \tclflushopt 0x12345678(%r8,%rcx,8)",},
715{{0x0f, 0xae, 0x38, }, 3, 0, "", "",
716"0f ae 38 \tclflush (%rax)",},
717{{0x41, 0x0f, 0xae, 0x38, }, 4, 0, "", "",
718"41 0f ae 38 \tclflush (%r8)",},
719{{0x0f, 0xae, 0xf8, }, 3, 0, "", "",
720"0f ae f8 \tsfence ",},
721{{0x66, 0x0f, 0xae, 0x30, }, 4, 0, "", "",
722"66 0f ae 30 \tclwb (%rax)",},
723{{0x66, 0x41, 0x0f, 0xae, 0x30, }, 5, 0, "", "",
724"66 41 0f ae 30 \tclwb (%r8)",},
725{{0x66, 0x0f, 0xae, 0x34, 0x25, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
726"66 0f ae 34 25 78 56 34 12 \tclwb 0x12345678",},
727{{0x66, 0x0f, 0xae, 0xb4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
728"66 0f ae b4 c8 78 56 34 12 \tclwb 0x12345678(%rax,%rcx,8)",},
729{{0x66, 0x41, 0x0f, 0xae, 0xb4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 10, 0, "", "",
730"66 41 0f ae b4 c8 78 56 34 12 \tclwb 0x12345678(%r8,%rcx,8)",},
731{{0x0f, 0xae, 0x30, }, 3, 0, "", "",
732"0f ae 30 \txsaveopt (%rax)",},
733{{0x41, 0x0f, 0xae, 0x30, }, 4, 0, "", "",
734"41 0f ae 30 \txsaveopt (%r8)",},
735{{0x0f, 0xae, 0xf0, }, 3, 0, "", "",
736"0f ae f0 \tmfence ",},
737{{0x0f, 0xc7, 0x20, }, 3, 0, "", "",
738"0f c7 20 \txsavec (%rax)",},
739{{0x41, 0x0f, 0xc7, 0x20, }, 4, 0, "", "",
740"41 0f c7 20 \txsavec (%r8)",},
741{{0x0f, 0xc7, 0x24, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
742"0f c7 24 25 78 56 34 12 \txsavec 0x12345678",},
743{{0x0f, 0xc7, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
744"0f c7 a4 c8 78 56 34 12 \txsavec 0x12345678(%rax,%rcx,8)",},
745{{0x41, 0x0f, 0xc7, 0xa4, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
746"41 0f c7 a4 c8 78 56 34 12 \txsavec 0x12345678(%r8,%rcx,8)",},
747{{0x0f, 0xc7, 0x28, }, 3, 0, "", "",
748"0f c7 28 \txsaves (%rax)",},
749{{0x41, 0x0f, 0xc7, 0x28, }, 4, 0, "", "",
750"41 0f c7 28 \txsaves (%r8)",},
751{{0x0f, 0xc7, 0x2c, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
752"0f c7 2c 25 78 56 34 12 \txsaves 0x12345678",},
753{{0x0f, 0xc7, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
754"0f c7 ac c8 78 56 34 12 \txsaves 0x12345678(%rax,%rcx,8)",},
755{{0x41, 0x0f, 0xc7, 0xac, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 9, 0, "", "",
756"41 0f c7 ac c8 78 56 34 12 \txsaves 0x12345678(%r8,%rcx,8)",},
757{{0x0f, 0xc7, 0x18, }, 3, 0, "", "",
758"0f c7 18 \txrstors (%rax)",},
759{{0x41, 0x0f, 0xc7, 0x18, }, 4, 0, "", "",
760"41 0f c7 18 \txrstors (%r8)",},
761{{0x0f, 0xc7, 0x1c, 0x25, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
762"0f c7 1c 25 78 56 34 12 \txrstors 0x12345678",},
763{{0x0f, 0xc7, 0x9c, 0xc8, 0x78, 0x56, 0x34, 0x12, }, 8, 0, "", "",
764"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, "", "",
766"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
new file mode 100644
index 000000000000..41b1b1c62660
--- /dev/null
+++ b/tools/perf/arch/x86/tests/insn-x86-dat-src.c
@@ -0,0 +1,877 @@
1/*
2 * This file contains instructions for testing by the test titled:
3 *
4 * "Test x86 instruction decoder - new instructions"
5 *
6 * Note that the 'Expecting' comment lines are consumed by the
7 * gen-insn-x86-dat.awk script and have the format:
8 *
9 * Expecting: <op> <branch> <rel>
10 *
11 * If this file is changed, remember to run the gen-insn-x86-dat.sh
12 * script and commit the result.
13 *
14 * Refer to insn-x86.c for more details.
15 */
16
17int main(void)
18{
19 /* Following line is a marker for the awk script - do not change */
20 asm volatile("rdtsc"); /* Start here */
21
22#ifdef __x86_64__
23
24 /* bndmk m64, bnd */
25
26 asm volatile("bndmk (%rax), %bnd0");
27 asm volatile("bndmk (%r8), %bnd0");
28 asm volatile("bndmk (0x12345678), %bnd0");
29 asm volatile("bndmk (%rax), %bnd3");
30 asm volatile("bndmk (%rcx,%rax,1), %bnd0");
31 asm volatile("bndmk 0x12345678(,%rax,1), %bnd0");
32 asm volatile("bndmk (%rax,%rcx,1), %bnd0");
33 asm volatile("bndmk (%rax,%rcx,8), %bnd0");
34 asm volatile("bndmk 0x12(%rax), %bnd0");
35 asm volatile("bndmk 0x12(%rbp), %bnd0");
36 asm volatile("bndmk 0x12(%rcx,%rax,1), %bnd0");
37 asm volatile("bndmk 0x12(%rbp,%rax,1), %bnd0");
38 asm volatile("bndmk 0x12(%rax,%rcx,1), %bnd0");
39 asm volatile("bndmk 0x12(%rax,%rcx,8), %bnd0");
40 asm volatile("bndmk 0x12345678(%rax), %bnd0");
41 asm volatile("bndmk 0x12345678(%rbp), %bnd0");
42 asm volatile("bndmk 0x12345678(%rcx,%rax,1), %bnd0");
43 asm volatile("bndmk 0x12345678(%rbp,%rax,1), %bnd0");
44 asm volatile("bndmk 0x12345678(%rax,%rcx,1), %bnd0");
45 asm volatile("bndmk 0x12345678(%rax,%rcx,8), %bnd0");
46
47 /* bndcl r/m64, bnd */
48
49 asm volatile("bndcl (%rax), %bnd0");
50 asm volatile("bndcl (%r8), %bnd0");
51 asm volatile("bndcl (0x12345678), %bnd0");
52 asm volatile("bndcl (%rax), %bnd3");
53 asm volatile("bndcl (%rcx,%rax,1), %bnd0");
54 asm volatile("bndcl 0x12345678(,%rax,1), %bnd0");
55 asm volatile("bndcl (%rax,%rcx,1), %bnd0");
56 asm volatile("bndcl (%rax,%rcx,8), %bnd0");
57 asm volatile("bndcl 0x12(%rax), %bnd0");
58 asm volatile("bndcl 0x12(%rbp), %bnd0");
59 asm volatile("bndcl 0x12(%rcx,%rax,1), %bnd0");
60 asm volatile("bndcl 0x12(%rbp,%rax,1), %bnd0");
61 asm volatile("bndcl 0x12(%rax,%rcx,1), %bnd0");
62 asm volatile("bndcl 0x12(%rax,%rcx,8), %bnd0");
63 asm volatile("bndcl 0x12345678(%rax), %bnd0");
64 asm volatile("bndcl 0x12345678(%rbp), %bnd0");
65 asm volatile("bndcl 0x12345678(%rcx,%rax,1), %bnd0");
66 asm volatile("bndcl 0x12345678(%rbp,%rax,1), %bnd0");
67 asm volatile("bndcl 0x12345678(%rax,%rcx,1), %bnd0");
68 asm volatile("bndcl 0x12345678(%rax,%rcx,8), %bnd0");
69 asm volatile("bndcl %rax, %bnd0");
70
71 /* bndcu r/m64, bnd */
72
73 asm volatile("bndcu (%rax), %bnd0");
74 asm volatile("bndcu (%r8), %bnd0");
75 asm volatile("bndcu (0x12345678), %bnd0");
76 asm volatile("bndcu (%rax), %bnd3");
77 asm volatile("bndcu (%rcx,%rax,1), %bnd0");
78 asm volatile("bndcu 0x12345678(,%rax,1), %bnd0");
79 asm volatile("bndcu (%rax,%rcx,1), %bnd0");
80 asm volatile("bndcu (%rax,%rcx,8), %bnd0");
81 asm volatile("bndcu 0x12(%rax), %bnd0");
82 asm volatile("bndcu 0x12(%rbp), %bnd0");
83 asm volatile("bndcu 0x12(%rcx,%rax,1), %bnd0");
84 asm volatile("bndcu 0x12(%rbp,%rax,1), %bnd0");
85 asm volatile("bndcu 0x12(%rax,%rcx,1), %bnd0");
86 asm volatile("bndcu 0x12(%rax,%rcx,8), %bnd0");
87 asm volatile("bndcu 0x12345678(%rax), %bnd0");
88 asm volatile("bndcu 0x12345678(%rbp), %bnd0");
89 asm volatile("bndcu 0x12345678(%rcx,%rax,1), %bnd0");
90 asm volatile("bndcu 0x12345678(%rbp,%rax,1), %bnd0");
91 asm volatile("bndcu 0x12345678(%rax,%rcx,1), %bnd0");
92 asm volatile("bndcu 0x12345678(%rax,%rcx,8), %bnd0");
93 asm volatile("bndcu %rax, %bnd0");
94
95 /* bndcn r/m64, bnd */
96
97 asm volatile("bndcn (%rax), %bnd0");
98 asm volatile("bndcn (%r8), %bnd0");
99 asm volatile("bndcn (0x12345678), %bnd0");
100 asm volatile("bndcn (%rax), %bnd3");
101 asm volatile("bndcn (%rcx,%rax,1), %bnd0");
102 asm volatile("bndcn 0x12345678(,%rax,1), %bnd0");
103 asm volatile("bndcn (%rax,%rcx,1), %bnd0");
104 asm volatile("bndcn (%rax,%rcx,8), %bnd0");
105 asm volatile("bndcn 0x12(%rax), %bnd0");
106 asm volatile("bndcn 0x12(%rbp), %bnd0");
107 asm volatile("bndcn 0x12(%rcx,%rax,1), %bnd0");
108 asm volatile("bndcn 0x12(%rbp,%rax,1), %bnd0");
109 asm volatile("bndcn 0x12(%rax,%rcx,1), %bnd0");
110 asm volatile("bndcn 0x12(%rax,%rcx,8), %bnd0");
111 asm volatile("bndcn 0x12345678(%rax), %bnd0");
112 asm volatile("bndcn 0x12345678(%rbp), %bnd0");
113 asm volatile("bndcn 0x12345678(%rcx,%rax,1), %bnd0");
114 asm volatile("bndcn 0x12345678(%rbp,%rax,1), %bnd0");
115 asm volatile("bndcn 0x12345678(%rax,%rcx,1), %bnd0");
116 asm volatile("bndcn 0x12345678(%rax,%rcx,8), %bnd0");
117 asm volatile("bndcn %rax, %bnd0");
118
119 /* bndmov m128, bnd */
120
121 asm volatile("bndmov (%rax), %bnd0");
122 asm volatile("bndmov (%r8), %bnd0");
123 asm volatile("bndmov (0x12345678), %bnd0");
124 asm volatile("bndmov (%rax), %bnd3");
125 asm volatile("bndmov (%rcx,%rax,1), %bnd0");
126 asm volatile("bndmov 0x12345678(,%rax,1), %bnd0");
127 asm volatile("bndmov (%rax,%rcx,1), %bnd0");
128 asm volatile("bndmov (%rax,%rcx,8), %bnd0");
129 asm volatile("bndmov 0x12(%rax), %bnd0");
130 asm volatile("bndmov 0x12(%rbp), %bnd0");
131 asm volatile("bndmov 0x12(%rcx,%rax,1), %bnd0");
132 asm volatile("bndmov 0x12(%rbp,%rax,1), %bnd0");
133 asm volatile("bndmov 0x12(%rax,%rcx,1), %bnd0");
134 asm volatile("bndmov 0x12(%rax,%rcx,8), %bnd0");
135 asm volatile("bndmov 0x12345678(%rax), %bnd0");
136 asm volatile("bndmov 0x12345678(%rbp), %bnd0");
137 asm volatile("bndmov 0x12345678(%rcx,%rax,1), %bnd0");
138 asm volatile("bndmov 0x12345678(%rbp,%rax,1), %bnd0");
139 asm volatile("bndmov 0x12345678(%rax,%rcx,1), %bnd0");
140 asm volatile("bndmov 0x12345678(%rax,%rcx,8), %bnd0");
141
142 /* bndmov bnd, m128 */
143
144 asm volatile("bndmov %bnd0, (%rax)");
145 asm volatile("bndmov %bnd0, (%r8)");
146 asm volatile("bndmov %bnd0, (0x12345678)");
147 asm volatile("bndmov %bnd3, (%rax)");
148 asm volatile("bndmov %bnd0, (%rcx,%rax,1)");
149 asm volatile("bndmov %bnd0, 0x12345678(,%rax,1)");
150 asm volatile("bndmov %bnd0, (%rax,%rcx,1)");
151 asm volatile("bndmov %bnd0, (%rax,%rcx,8)");
152 asm volatile("bndmov %bnd0, 0x12(%rax)");
153 asm volatile("bndmov %bnd0, 0x12(%rbp)");
154 asm volatile("bndmov %bnd0, 0x12(%rcx,%rax,1)");
155 asm volatile("bndmov %bnd0, 0x12(%rbp,%rax,1)");
156 asm volatile("bndmov %bnd0, 0x12(%rax,%rcx,1)");
157 asm volatile("bndmov %bnd0, 0x12(%rax,%rcx,8)");
158 asm volatile("bndmov %bnd0, 0x12345678(%rax)");
159 asm volatile("bndmov %bnd0, 0x12345678(%rbp)");
160 asm volatile("bndmov %bnd0, 0x12345678(%rcx,%rax,1)");
161 asm volatile("bndmov %bnd0, 0x12345678(%rbp,%rax,1)");
162 asm volatile("bndmov %bnd0, 0x12345678(%rax,%rcx,1)");
163 asm volatile("bndmov %bnd0, 0x12345678(%rax,%rcx,8)");
164
165 /* bndmov bnd2, bnd1 */
166
167 asm volatile("bndmov %bnd0, %bnd1");
168 asm volatile("bndmov %bnd1, %bnd0");
169
170 /* bndldx mib, bnd */
171
172 asm volatile("bndldx (%rax), %bnd0");
173 asm volatile("bndldx (%r8), %bnd0");
174 asm volatile("bndldx (0x12345678), %bnd0");
175 asm volatile("bndldx (%rax), %bnd3");
176 asm volatile("bndldx (%rcx,%rax,1), %bnd0");
177 asm volatile("bndldx 0x12345678(,%rax,1), %bnd0");
178 asm volatile("bndldx (%rax,%rcx,1), %bnd0");
179 asm volatile("bndldx 0x12(%rax), %bnd0");
180 asm volatile("bndldx 0x12(%rbp), %bnd0");
181 asm volatile("bndldx 0x12(%rcx,%rax,1), %bnd0");
182 asm volatile("bndldx 0x12(%rbp,%rax,1), %bnd0");
183 asm volatile("bndldx 0x12(%rax,%rcx,1), %bnd0");
184 asm volatile("bndldx 0x12345678(%rax), %bnd0");
185 asm volatile("bndldx 0x12345678(%rbp), %bnd0");
186 asm volatile("bndldx 0x12345678(%rcx,%rax,1), %bnd0");
187 asm volatile("bndldx 0x12345678(%rbp,%rax,1), %bnd0");
188 asm volatile("bndldx 0x12345678(%rax,%rcx,1), %bnd0");
189
190 /* bndstx bnd, mib */
191
192 asm volatile("bndstx %bnd0, (%rax)");
193 asm volatile("bndstx %bnd0, (%r8)");
194 asm volatile("bndstx %bnd0, (0x12345678)");
195 asm volatile("bndstx %bnd3, (%rax)");
196 asm volatile("bndstx %bnd0, (%rcx,%rax,1)");
197 asm volatile("bndstx %bnd0, 0x12345678(,%rax,1)");
198 asm volatile("bndstx %bnd0, (%rax,%rcx,1)");
199 asm volatile("bndstx %bnd0, 0x12(%rax)");
200 asm volatile("bndstx %bnd0, 0x12(%rbp)");
201 asm volatile("bndstx %bnd0, 0x12(%rcx,%rax,1)");
202 asm volatile("bndstx %bnd0, 0x12(%rbp,%rax,1)");
203 asm volatile("bndstx %bnd0, 0x12(%rax,%rcx,1)");
204 asm volatile("bndstx %bnd0, 0x12345678(%rax)");
205 asm volatile("bndstx %bnd0, 0x12345678(%rbp)");
206 asm volatile("bndstx %bnd0, 0x12345678(%rcx,%rax,1)");
207 asm volatile("bndstx %bnd0, 0x12345678(%rbp,%rax,1)");
208 asm volatile("bndstx %bnd0, 0x12345678(%rax,%rcx,1)");
209
210 /* bnd prefix on call, ret, jmp and all jcc */
211
212 asm volatile("bnd call label1"); /* Expecting: call unconditional 0 */
213 asm volatile("bnd call *(%eax)"); /* Expecting: call indirect 0 */
214 asm volatile("bnd ret"); /* Expecting: ret indirect 0 */
215 asm volatile("bnd jmp label1"); /* Expecting: jmp unconditional 0 */
216 asm volatile("bnd jmp label1"); /* Expecting: jmp unconditional 0 */
217 asm volatile("bnd jmp *(%ecx)"); /* Expecting: jmp indirect 0 */
218 asm volatile("bnd jne label1"); /* Expecting: jcc conditional 0 */
219
220 /* sha1rnds4 imm8, xmm2/m128, xmm1 */
221
222 asm volatile("sha1rnds4 $0x0, %xmm1, %xmm0");
223 asm volatile("sha1rnds4 $0x91, %xmm7, %xmm2");
224 asm volatile("sha1rnds4 $0x91, %xmm8, %xmm0");
225 asm volatile("sha1rnds4 $0x91, %xmm7, %xmm8");
226 asm volatile("sha1rnds4 $0x91, %xmm15, %xmm8");
227 asm volatile("sha1rnds4 $0x91, (%rax), %xmm0");
228 asm volatile("sha1rnds4 $0x91, (%r8), %xmm0");
229 asm volatile("sha1rnds4 $0x91, (0x12345678), %xmm0");
230 asm volatile("sha1rnds4 $0x91, (%rax), %xmm3");
231 asm volatile("sha1rnds4 $0x91, (%rcx,%rax,1), %xmm0");
232 asm volatile("sha1rnds4 $0x91, 0x12345678(,%rax,1), %xmm0");
233 asm volatile("sha1rnds4 $0x91, (%rax,%rcx,1), %xmm0");
234 asm volatile("sha1rnds4 $0x91, (%rax,%rcx,8), %xmm0");
235 asm volatile("sha1rnds4 $0x91, 0x12(%rax), %xmm0");
236 asm volatile("sha1rnds4 $0x91, 0x12(%rbp), %xmm0");
237 asm volatile("sha1rnds4 $0x91, 0x12(%rcx,%rax,1), %xmm0");
238 asm volatile("sha1rnds4 $0x91, 0x12(%rbp,%rax,1), %xmm0");
239 asm volatile("sha1rnds4 $0x91, 0x12(%rax,%rcx,1), %xmm0");
240 asm volatile("sha1rnds4 $0x91, 0x12(%rax,%rcx,8), %xmm0");
241 asm volatile("sha1rnds4 $0x91, 0x12345678(%rax), %xmm0");
242 asm volatile("sha1rnds4 $0x91, 0x12345678(%rbp), %xmm0");
243 asm volatile("sha1rnds4 $0x91, 0x12345678(%rcx,%rax,1), %xmm0");
244 asm volatile("sha1rnds4 $0x91, 0x12345678(%rbp,%rax,1), %xmm0");
245 asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,1), %xmm0");
246 asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,8), %xmm0");
247 asm volatile("sha1rnds4 $0x91, 0x12345678(%rax,%rcx,8), %xmm15");
248
249 /* sha1nexte xmm2/m128, xmm1 */
250
251 asm volatile("sha1nexte %xmm1, %xmm0");
252 asm volatile("sha1nexte %xmm7, %xmm2");
253 asm volatile("sha1nexte %xmm8, %xmm0");
254 asm volatile("sha1nexte %xmm7, %xmm8");
255 asm volatile("sha1nexte %xmm15, %xmm8");
256 asm volatile("sha1nexte (%rax), %xmm0");
257 asm volatile("sha1nexte (%r8), %xmm0");
258 asm volatile("sha1nexte (0x12345678), %xmm0");
259 asm volatile("sha1nexte (%rax), %xmm3");
260 asm volatile("sha1nexte (%rcx,%rax,1), %xmm0");
261 asm volatile("sha1nexte 0x12345678(,%rax,1), %xmm0");
262 asm volatile("sha1nexte (%rax,%rcx,1), %xmm0");
263 asm volatile("sha1nexte (%rax,%rcx,8), %xmm0");
264 asm volatile("sha1nexte 0x12(%rax), %xmm0");
265 asm volatile("sha1nexte 0x12(%rbp), %xmm0");
266 asm volatile("sha1nexte 0x12(%rcx,%rax,1), %xmm0");
267 asm volatile("sha1nexte 0x12(%rbp,%rax,1), %xmm0");
268 asm volatile("sha1nexte 0x12(%rax,%rcx,1), %xmm0");
269 asm volatile("sha1nexte 0x12(%rax,%rcx,8), %xmm0");
270 asm volatile("sha1nexte 0x12345678(%rax), %xmm0");
271 asm volatile("sha1nexte 0x12345678(%rbp), %xmm0");
272 asm volatile("sha1nexte 0x12345678(%rcx,%rax,1), %xmm0");
273 asm volatile("sha1nexte 0x12345678(%rbp,%rax,1), %xmm0");
274 asm volatile("sha1nexte 0x12345678(%rax,%rcx,1), %xmm0");
275 asm volatile("sha1nexte 0x12345678(%rax,%rcx,8), %xmm0");
276 asm volatile("sha1nexte 0x12345678(%rax,%rcx,8), %xmm15");
277
278 /* sha1msg1 xmm2/m128, xmm1 */
279
280 asm volatile("sha1msg1 %xmm1, %xmm0");
281 asm volatile("sha1msg1 %xmm7, %xmm2");
282 asm volatile("sha1msg1 %xmm8, %xmm0");
283 asm volatile("sha1msg1 %xmm7, %xmm8");
284 asm volatile("sha1msg1 %xmm15, %xmm8");
285 asm volatile("sha1msg1 (%rax), %xmm0");
286 asm volatile("sha1msg1 (%r8), %xmm0");
287 asm volatile("sha1msg1 (0x12345678), %xmm0");
288 asm volatile("sha1msg1 (%rax), %xmm3");
289 asm volatile("sha1msg1 (%rcx,%rax,1), %xmm0");
290 asm volatile("sha1msg1 0x12345678(,%rax,1), %xmm0");
291 asm volatile("sha1msg1 (%rax,%rcx,1), %xmm0");
292 asm volatile("sha1msg1 (%rax,%rcx,8), %xmm0");
293 asm volatile("sha1msg1 0x12(%rax), %xmm0");
294 asm volatile("sha1msg1 0x12(%rbp), %xmm0");
295 asm volatile("sha1msg1 0x12(%rcx,%rax,1), %xmm0");
296 asm volatile("sha1msg1 0x12(%rbp,%rax,1), %xmm0");
297 asm volatile("sha1msg1 0x12(%rax,%rcx,1), %xmm0");
298 asm volatile("sha1msg1 0x12(%rax,%rcx,8), %xmm0");
299 asm volatile("sha1msg1 0x12345678(%rax), %xmm0");
300 asm volatile("sha1msg1 0x12345678(%rbp), %xmm0");
301 asm volatile("sha1msg1 0x12345678(%rcx,%rax,1), %xmm0");
302 asm volatile("sha1msg1 0x12345678(%rbp,%rax,1), %xmm0");
303 asm volatile("sha1msg1 0x12345678(%rax,%rcx,1), %xmm0");
304 asm volatile("sha1msg1 0x12345678(%rax,%rcx,8), %xmm0");
305 asm volatile("sha1msg1 0x12345678(%rax,%rcx,8), %xmm15");
306
307 /* sha1msg2 xmm2/m128, xmm1 */
308
309 asm volatile("sha1msg2 %xmm1, %xmm0");
310 asm volatile("sha1msg2 %xmm7, %xmm2");
311 asm volatile("sha1msg2 %xmm8, %xmm0");
312 asm volatile("sha1msg2 %xmm7, %xmm8");
313 asm volatile("sha1msg2 %xmm15, %xmm8");
314 asm volatile("sha1msg2 (%rax), %xmm0");
315 asm volatile("sha1msg2 (%r8), %xmm0");
316 asm volatile("sha1msg2 (0x12345678), %xmm0");
317 asm volatile("sha1msg2 (%rax), %xmm3");
318 asm volatile("sha1msg2 (%rcx,%rax,1), %xmm0");
319 asm volatile("sha1msg2 0x12345678(,%rax,1), %xmm0");
320 asm volatile("sha1msg2 (%rax,%rcx,1), %xmm0");
321 asm volatile("sha1msg2 (%rax,%rcx,8), %xmm0");
322 asm volatile("sha1msg2 0x12(%rax), %xmm0");
323 asm volatile("sha1msg2 0x12(%rbp), %xmm0");
324 asm volatile("sha1msg2 0x12(%rcx,%rax,1), %xmm0");
325 asm volatile("sha1msg2 0x12(%rbp,%rax,1), %xmm0");
326 asm volatile("sha1msg2 0x12(%rax,%rcx,1), %xmm0");
327 asm volatile("sha1msg2 0x12(%rax,%rcx,8), %xmm0");
328 asm volatile("sha1msg2 0x12345678(%rax), %xmm0");
329 asm volatile("sha1msg2 0x12345678(%rbp), %xmm0");
330 asm volatile("sha1msg2 0x12345678(%rcx,%rax,1), %xmm0");
331 asm volatile("sha1msg2 0x12345678(%rbp,%rax,1), %xmm0");
332 asm volatile("sha1msg2 0x12345678(%rax,%rcx,1), %xmm0");
333 asm volatile("sha1msg2 0x12345678(%rax,%rcx,8), %xmm0");
334 asm volatile("sha1msg2 0x12345678(%rax,%rcx,8), %xmm15");
335
336 /* sha256rnds2 <XMM0>, xmm2/m128, xmm1 */
337 /* Note sha256rnds2 has an implicit operand 'xmm0' */
338
339 asm volatile("sha256rnds2 %xmm4, %xmm1");
340 asm volatile("sha256rnds2 %xmm7, %xmm2");
341 asm volatile("sha256rnds2 %xmm8, %xmm1");
342 asm volatile("sha256rnds2 %xmm7, %xmm8");
343 asm volatile("sha256rnds2 %xmm15, %xmm8");
344 asm volatile("sha256rnds2 (%rax), %xmm1");
345 asm volatile("sha256rnds2 (%r8), %xmm1");
346 asm volatile("sha256rnds2 (0x12345678), %xmm1");
347 asm volatile("sha256rnds2 (%rax), %xmm3");
348 asm volatile("sha256rnds2 (%rcx,%rax,1), %xmm1");
349 asm volatile("sha256rnds2 0x12345678(,%rax,1), %xmm1");
350 asm volatile("sha256rnds2 (%rax,%rcx,1), %xmm1");
351 asm volatile("sha256rnds2 (%rax,%rcx,8), %xmm1");
352 asm volatile("sha256rnds2 0x12(%rax), %xmm1");
353 asm volatile("sha256rnds2 0x12(%rbp), %xmm1");
354 asm volatile("sha256rnds2 0x12(%rcx,%rax,1), %xmm1");
355 asm volatile("sha256rnds2 0x12(%rbp,%rax,1), %xmm1");
356 asm volatile("sha256rnds2 0x12(%rax,%rcx,1), %xmm1");
357 asm volatile("sha256rnds2 0x12(%rax,%rcx,8), %xmm1");
358 asm volatile("sha256rnds2 0x12345678(%rax), %xmm1");
359 asm volatile("sha256rnds2 0x12345678(%rbp), %xmm1");
360 asm volatile("sha256rnds2 0x12345678(%rcx,%rax,1), %xmm1");
361 asm volatile("sha256rnds2 0x12345678(%rbp,%rax,1), %xmm1");
362 asm volatile("sha256rnds2 0x12345678(%rax,%rcx,1), %xmm1");
363 asm volatile("sha256rnds2 0x12345678(%rax,%rcx,8), %xmm1");
364 asm volatile("sha256rnds2 0x12345678(%rax,%rcx,8), %xmm15");
365
366 /* sha256msg1 xmm2/m128, xmm1 */
367
368 asm volatile("sha256msg1 %xmm1, %xmm0");
369 asm volatile("sha256msg1 %xmm7, %xmm2");
370 asm volatile("sha256msg1 %xmm8, %xmm0");
371 asm volatile("sha256msg1 %xmm7, %xmm8");
372 asm volatile("sha256msg1 %xmm15, %xmm8");
373 asm volatile("sha256msg1 (%rax), %xmm0");
374 asm volatile("sha256msg1 (%r8), %xmm0");
375 asm volatile("sha256msg1 (0x12345678), %xmm0");
376 asm volatile("sha256msg1 (%rax), %xmm3");
377 asm volatile("sha256msg1 (%rcx,%rax,1), %xmm0");
378 asm volatile("sha256msg1 0x12345678(,%rax,1), %xmm0");
379 asm volatile("sha256msg1 (%rax,%rcx,1), %xmm0");
380 asm volatile("sha256msg1 (%rax,%rcx,8), %xmm0");
381 asm volatile("sha256msg1 0x12(%rax), %xmm0");
382 asm volatile("sha256msg1 0x12(%rbp), %xmm0");
383 asm volatile("sha256msg1 0x12(%rcx,%rax,1), %xmm0");
384 asm volatile("sha256msg1 0x12(%rbp,%rax,1), %xmm0");
385 asm volatile("sha256msg1 0x12(%rax,%rcx,1), %xmm0");
386 asm volatile("sha256msg1 0x12(%rax,%rcx,8), %xmm0");
387 asm volatile("sha256msg1 0x12345678(%rax), %xmm0");
388 asm volatile("sha256msg1 0x12345678(%rbp), %xmm0");
389 asm volatile("sha256msg1 0x12345678(%rcx,%rax,1), %xmm0");
390 asm volatile("sha256msg1 0x12345678(%rbp,%rax,1), %xmm0");
391 asm volatile("sha256msg1 0x12345678(%rax,%rcx,1), %xmm0");
392 asm volatile("sha256msg1 0x12345678(%rax,%rcx,8), %xmm0");
393 asm volatile("sha256msg1 0x12345678(%rax,%rcx,8), %xmm15");
394
395 /* sha256msg2 xmm2/m128, xmm1 */
396
397 asm volatile("sha256msg2 %xmm1, %xmm0");
398 asm volatile("sha256msg2 %xmm7, %xmm2");
399 asm volatile("sha256msg2 %xmm8, %xmm0");
400 asm volatile("sha256msg2 %xmm7, %xmm8");
401 asm volatile("sha256msg2 %xmm15, %xmm8");
402 asm volatile("sha256msg2 (%rax), %xmm0");
403 asm volatile("sha256msg2 (%r8), %xmm0");
404 asm volatile("sha256msg2 (0x12345678), %xmm0");
405 asm volatile("sha256msg2 (%rax), %xmm3");
406 asm volatile("sha256msg2 (%rcx,%rax,1), %xmm0");
407 asm volatile("sha256msg2 0x12345678(,%rax,1), %xmm0");
408 asm volatile("sha256msg2 (%rax,%rcx,1), %xmm0");
409 asm volatile("sha256msg2 (%rax,%rcx,8), %xmm0");
410 asm volatile("sha256msg2 0x12(%rax), %xmm0");
411 asm volatile("sha256msg2 0x12(%rbp), %xmm0");
412 asm volatile("sha256msg2 0x12(%rcx,%rax,1), %xmm0");
413 asm volatile("sha256msg2 0x12(%rbp,%rax,1), %xmm0");
414 asm volatile("sha256msg2 0x12(%rax,%rcx,1), %xmm0");
415 asm volatile("sha256msg2 0x12(%rax,%rcx,8), %xmm0");
416 asm volatile("sha256msg2 0x12345678(%rax), %xmm0");
417 asm volatile("sha256msg2 0x12345678(%rbp), %xmm0");
418 asm volatile("sha256msg2 0x12345678(%rcx,%rax,1), %xmm0");
419 asm volatile("sha256msg2 0x12345678(%rbp,%rax,1), %xmm0");
420 asm volatile("sha256msg2 0x12345678(%rax,%rcx,1), %xmm0");
421 asm volatile("sha256msg2 0x12345678(%rax,%rcx,8), %xmm0");
422 asm volatile("sha256msg2 0x12345678(%rax,%rcx,8), %xmm15");
423
424 /* clflushopt m8 */
425
426 asm volatile("clflushopt (%rax)");
427 asm volatile("clflushopt (%r8)");
428 asm volatile("clflushopt (0x12345678)");
429 asm volatile("clflushopt 0x12345678(%rax,%rcx,8)");
430 asm volatile("clflushopt 0x12345678(%r8,%rcx,8)");
431 /* Also check instructions in the same group encoding as clflushopt */
432 asm volatile("clflush (%rax)");
433 asm volatile("clflush (%r8)");
434 asm volatile("sfence");
435
436 /* clwb m8 */
437
438 asm volatile("clwb (%rax)");
439 asm volatile("clwb (%r8)");
440 asm volatile("clwb (0x12345678)");
441 asm volatile("clwb 0x12345678(%rax,%rcx,8)");
442 asm volatile("clwb 0x12345678(%r8,%rcx,8)");
443 /* Also check instructions in the same group encoding as clwb */
444 asm volatile("xsaveopt (%rax)");
445 asm volatile("xsaveopt (%r8)");
446 asm volatile("mfence");
447
448 /* xsavec mem */
449
450 asm volatile("xsavec (%rax)");
451 asm volatile("xsavec (%r8)");
452 asm volatile("xsavec (0x12345678)");
453 asm volatile("xsavec 0x12345678(%rax,%rcx,8)");
454 asm volatile("xsavec 0x12345678(%r8,%rcx,8)");
455
456 /* xsaves mem */
457
458 asm volatile("xsaves (%rax)");
459 asm volatile("xsaves (%r8)");
460 asm volatile("xsaves (0x12345678)");
461 asm volatile("xsaves 0x12345678(%rax,%rcx,8)");
462 asm volatile("xsaves 0x12345678(%r8,%rcx,8)");
463
464 /* xrstors mem */
465
466 asm volatile("xrstors (%rax)");
467 asm volatile("xrstors (%r8)");
468 asm volatile("xrstors (0x12345678)");
469 asm volatile("xrstors 0x12345678(%rax,%rcx,8)");
470 asm volatile("xrstors 0x12345678(%r8,%rcx,8)");
471
472#else /* #ifdef __x86_64__ */
473
474 /* bndmk m32, bnd */
475
476 asm volatile("bndmk (%eax), %bnd0");
477 asm volatile("bndmk (0x12345678), %bnd0");
478 asm volatile("bndmk (%eax), %bnd3");
479 asm volatile("bndmk (%ecx,%eax,1), %bnd0");
480 asm volatile("bndmk 0x12345678(,%eax,1), %bnd0");
481 asm volatile("bndmk (%eax,%ecx,1), %bnd0");
482 asm volatile("bndmk (%eax,%ecx,8), %bnd0");
483 asm volatile("bndmk 0x12(%eax), %bnd0");
484 asm volatile("bndmk 0x12(%ebp), %bnd0");
485 asm volatile("bndmk 0x12(%ecx,%eax,1), %bnd0");
486 asm volatile("bndmk 0x12(%ebp,%eax,1), %bnd0");
487 asm volatile("bndmk 0x12(%eax,%ecx,1), %bnd0");
488 asm volatile("bndmk 0x12(%eax,%ecx,8), %bnd0");
489 asm volatile("bndmk 0x12345678(%eax), %bnd0");
490 asm volatile("bndmk 0x12345678(%ebp), %bnd0");
491 asm volatile("bndmk 0x12345678(%ecx,%eax,1), %bnd0");
492 asm volatile("bndmk 0x12345678(%ebp,%eax,1), %bnd0");
493 asm volatile("bndmk 0x12345678(%eax,%ecx,1), %bnd0");
494 asm volatile("bndmk 0x12345678(%eax,%ecx,8), %bnd0");
495
496 /* bndcl r/m32, bnd */
497
498 asm volatile("bndcl (%eax), %bnd0");
499 asm volatile("bndcl (0x12345678), %bnd0");
500 asm volatile("bndcl (%eax), %bnd3");
501 asm volatile("bndcl (%ecx,%eax,1), %bnd0");
502 asm volatile("bndcl 0x12345678(,%eax,1), %bnd0");
503 asm volatile("bndcl (%eax,%ecx,1), %bnd0");
504 asm volatile("bndcl (%eax,%ecx,8), %bnd0");
505 asm volatile("bndcl 0x12(%eax), %bnd0");
506 asm volatile("bndcl 0x12(%ebp), %bnd0");
507 asm volatile("bndcl 0x12(%ecx,%eax,1), %bnd0");
508 asm volatile("bndcl 0x12(%ebp,%eax,1), %bnd0");
509 asm volatile("bndcl 0x12(%eax,%ecx,1), %bnd0");
510 asm volatile("bndcl 0x12(%eax,%ecx,8), %bnd0");
511 asm volatile("bndcl 0x12345678(%eax), %bnd0");
512 asm volatile("bndcl 0x12345678(%ebp), %bnd0");
513 asm volatile("bndcl 0x12345678(%ecx,%eax,1), %bnd0");
514 asm volatile("bndcl 0x12345678(%ebp,%eax,1), %bnd0");
515 asm volatile("bndcl 0x12345678(%eax,%ecx,1), %bnd0");
516 asm volatile("bndcl 0x12345678(%eax,%ecx,8), %bnd0");
517 asm volatile("bndcl %eax, %bnd0");
518
519 /* bndcu r/m32, bnd */
520
521 asm volatile("bndcu (%eax), %bnd0");
522 asm volatile("bndcu (0x12345678), %bnd0");
523 asm volatile("bndcu (%eax), %bnd3");
524 asm volatile("bndcu (%ecx,%eax,1), %bnd0");
525 asm volatile("bndcu 0x12345678(,%eax,1), %bnd0");
526 asm volatile("bndcu (%eax,%ecx,1), %bnd0");
527 asm volatile("bndcu (%eax,%ecx,8), %bnd0");
528 asm volatile("bndcu 0x12(%eax), %bnd0");
529 asm volatile("bndcu 0x12(%ebp), %bnd0");
530 asm volatile("bndcu 0x12(%ecx,%eax,1), %bnd0");
531 asm volatile("bndcu 0x12(%ebp,%eax,1), %bnd0");
532 asm volatile("bndcu 0x12(%eax,%ecx,1), %bnd0");
533 asm volatile("bndcu 0x12(%eax,%ecx,8), %bnd0");
534 asm volatile("bndcu 0x12345678(%eax), %bnd0");
535 asm volatile("bndcu 0x12345678(%ebp), %bnd0");
536 asm volatile("bndcu 0x12345678(%ecx,%eax,1), %bnd0");
537 asm volatile("bndcu 0x12345678(%ebp,%eax,1), %bnd0");
538 asm volatile("bndcu 0x12345678(%eax,%ecx,1), %bnd0");
539 asm volatile("bndcu 0x12345678(%eax,%ecx,8), %bnd0");
540 asm volatile("bndcu %eax, %bnd0");
541
542 /* bndcn r/m32, bnd */
543
544 asm volatile("bndcn (%eax), %bnd0");
545 asm volatile("bndcn (0x12345678), %bnd0");
546 asm volatile("bndcn (%eax), %bnd3");
547 asm volatile("bndcn (%ecx,%eax,1), %bnd0");
548 asm volatile("bndcn 0x12345678(,%eax,1), %bnd0");
549 asm volatile("bndcn (%eax,%ecx,1), %bnd0");
550 asm volatile("bndcn (%eax,%ecx,8), %bnd0");
551 asm volatile("bndcn 0x12(%eax), %bnd0");
552 asm volatile("bndcn 0x12(%ebp), %bnd0");
553 asm volatile("bndcn 0x12(%ecx,%eax,1), %bnd0");
554 asm volatile("bndcn 0x12(%ebp,%eax,1), %bnd0");
555 asm volatile("bndcn 0x12(%eax,%ecx,1), %bnd0");
556 asm volatile("bndcn 0x12(%eax,%ecx,8), %bnd0");
557 asm volatile("bndcn 0x12345678(%eax), %bnd0");
558 asm volatile("bndcn 0x12345678(%ebp), %bnd0");
559 asm volatile("bndcn 0x12345678(%ecx,%eax,1), %bnd0");
560 asm volatile("bndcn 0x12345678(%ebp,%eax,1), %bnd0");
561 asm volatile("bndcn 0x12345678(%eax,%ecx,1), %bnd0");
562 asm volatile("bndcn 0x12345678(%eax,%ecx,8), %bnd0");
563 asm volatile("bndcn %eax, %bnd0");
564
565 /* bndmov m64, bnd */
566
567 asm volatile("bndmov (%eax), %bnd0");
568 asm volatile("bndmov (0x12345678), %bnd0");
569 asm volatile("bndmov (%eax), %bnd3");
570 asm volatile("bndmov (%ecx,%eax,1), %bnd0");
571 asm volatile("bndmov 0x12345678(,%eax,1), %bnd0");
572 asm volatile("bndmov (%eax,%ecx,1), %bnd0");
573 asm volatile("bndmov (%eax,%ecx,8), %bnd0");
574 asm volatile("bndmov 0x12(%eax), %bnd0");
575 asm volatile("bndmov 0x12(%ebp), %bnd0");
576 asm volatile("bndmov 0x12(%ecx,%eax,1), %bnd0");
577 asm volatile("bndmov 0x12(%ebp,%eax,1), %bnd0");
578 asm volatile("bndmov 0x12(%eax,%ecx,1), %bnd0");
579 asm volatile("bndmov 0x12(%eax,%ecx,8), %bnd0");
580 asm volatile("bndmov 0x12345678(%eax), %bnd0");
581 asm volatile("bndmov 0x12345678(%ebp), %bnd0");
582 asm volatile("bndmov 0x12345678(%ecx,%eax,1), %bnd0");
583 asm volatile("bndmov 0x12345678(%ebp,%eax,1), %bnd0");
584 asm volatile("bndmov 0x12345678(%eax,%ecx,1), %bnd0");
585 asm volatile("bndmov 0x12345678(%eax,%ecx,8), %bnd0");
586
587 /* bndmov bnd, m64 */
588
589 asm volatile("bndmov %bnd0, (%eax)");
590 asm volatile("bndmov %bnd0, (0x12345678)");
591 asm volatile("bndmov %bnd3, (%eax)");
592 asm volatile("bndmov %bnd0, (%ecx,%eax,1)");
593 asm volatile("bndmov %bnd0, 0x12345678(,%eax,1)");
594 asm volatile("bndmov %bnd0, (%eax,%ecx,1)");
595 asm volatile("bndmov %bnd0, (%eax,%ecx,8)");
596 asm volatile("bndmov %bnd0, 0x12(%eax)");
597 asm volatile("bndmov %bnd0, 0x12(%ebp)");
598 asm volatile("bndmov %bnd0, 0x12(%ecx,%eax,1)");
599 asm volatile("bndmov %bnd0, 0x12(%ebp,%eax,1)");
600 asm volatile("bndmov %bnd0, 0x12(%eax,%ecx,1)");
601 asm volatile("bndmov %bnd0, 0x12(%eax,%ecx,8)");
602 asm volatile("bndmov %bnd0, 0x12345678(%eax)");
603 asm volatile("bndmov %bnd0, 0x12345678(%ebp)");
604 asm volatile("bndmov %bnd0, 0x12345678(%ecx,%eax,1)");
605 asm volatile("bndmov %bnd0, 0x12345678(%ebp,%eax,1)");
606 asm volatile("bndmov %bnd0, 0x12345678(%eax,%ecx,1)");
607 asm volatile("bndmov %bnd0, 0x12345678(%eax,%ecx,8)");
608
609 /* bndmov bnd2, bnd1 */
610
611 asm volatile("bndmov %bnd0, %bnd1");
612 asm volatile("bndmov %bnd1, %bnd0");
613
614 /* bndldx mib, bnd */
615
616 asm volatile("bndldx (%eax), %bnd0");
617 asm volatile("bndldx (0x12345678), %bnd0");
618 asm volatile("bndldx (%eax), %bnd3");
619 asm volatile("bndldx (%ecx,%eax,1), %bnd0");
620 asm volatile("bndldx 0x12345678(,%eax,1), %bnd0");
621 asm volatile("bndldx (%eax,%ecx,1), %bnd0");
622 asm volatile("bndldx 0x12(%eax), %bnd0");
623 asm volatile("bndldx 0x12(%ebp), %bnd0");
624 asm volatile("bndldx 0x12(%ecx,%eax,1), %bnd0");
625 asm volatile("bndldx 0x12(%ebp,%eax,1), %bnd0");
626 asm volatile("bndldx 0x12(%eax,%ecx,1), %bnd0");
627 asm volatile("bndldx 0x12345678(%eax), %bnd0");
628 asm volatile("bndldx 0x12345678(%ebp), %bnd0");
629 asm volatile("bndldx 0x12345678(%ecx,%eax,1), %bnd0");
630 asm volatile("bndldx 0x12345678(%ebp,%eax,1), %bnd0");
631 asm volatile("bndldx 0x12345678(%eax,%ecx,1), %bnd0");
632
633 /* bndstx bnd, mib */
634
635 asm volatile("bndstx %bnd0, (%eax)");
636 asm volatile("bndstx %bnd0, (0x12345678)");
637 asm volatile("bndstx %bnd3, (%eax)");
638 asm volatile("bndstx %bnd0, (%ecx,%eax,1)");
639 asm volatile("bndstx %bnd0, 0x12345678(,%eax,1)");
640 asm volatile("bndstx %bnd0, (%eax,%ecx,1)");
641 asm volatile("bndstx %bnd0, 0x12(%eax)");
642 asm volatile("bndstx %bnd0, 0x12(%ebp)");
643 asm volatile("bndstx %bnd0, 0x12(%ecx,%eax,1)");
644 asm volatile("bndstx %bnd0, 0x12(%ebp,%eax,1)");
645 asm volatile("bndstx %bnd0, 0x12(%eax,%ecx,1)");
646 asm volatile("bndstx %bnd0, 0x12345678(%eax)");
647 asm volatile("bndstx %bnd0, 0x12345678(%ebp)");
648 asm volatile("bndstx %bnd0, 0x12345678(%ecx,%eax,1)");
649 asm volatile("bndstx %bnd0, 0x12345678(%ebp,%eax,1)");
650 asm volatile("bndstx %bnd0, 0x12345678(%eax,%ecx,1)");
651
652 /* bnd prefix on call, ret, jmp and all jcc */
653
654 asm volatile("bnd call label1"); /* Expecting: call unconditional 0xfffffffc */
655 asm volatile("bnd call *(%eax)"); /* Expecting: call indirect 0 */
656 asm volatile("bnd ret"); /* Expecting: ret indirect 0 */
657 asm volatile("bnd jmp label1"); /* Expecting: jmp unconditional 0xfffffffc */
658 asm volatile("bnd jmp label1"); /* Expecting: jmp unconditional 0xfffffffc */
659 asm volatile("bnd jmp *(%ecx)"); /* Expecting: jmp indirect 0 */
660 asm volatile("bnd jne label1"); /* Expecting: jcc conditional 0xfffffffc */
661
662 /* sha1rnds4 imm8, xmm2/m128, xmm1 */
663
664 asm volatile("sha1rnds4 $0x0, %xmm1, %xmm0");
665 asm volatile("sha1rnds4 $0x91, %xmm7, %xmm2");
666 asm volatile("sha1rnds4 $0x91, (%eax), %xmm0");
667 asm volatile("sha1rnds4 $0x91, (0x12345678), %xmm0");
668 asm volatile("sha1rnds4 $0x91, (%eax), %xmm3");
669 asm volatile("sha1rnds4 $0x91, (%ecx,%eax,1), %xmm0");
670 asm volatile("sha1rnds4 $0x91, 0x12345678(,%eax,1), %xmm0");
671 asm volatile("sha1rnds4 $0x91, (%eax,%ecx,1), %xmm0");
672 asm volatile("sha1rnds4 $0x91, (%eax,%ecx,8), %xmm0");
673 asm volatile("sha1rnds4 $0x91, 0x12(%eax), %xmm0");
674 asm volatile("sha1rnds4 $0x91, 0x12(%ebp), %xmm0");
675 asm volatile("sha1rnds4 $0x91, 0x12(%ecx,%eax,1), %xmm0");
676 asm volatile("sha1rnds4 $0x91, 0x12(%ebp,%eax,1), %xmm0");
677 asm volatile("sha1rnds4 $0x91, 0x12(%eax,%ecx,1), %xmm0");
678 asm volatile("sha1rnds4 $0x91, 0x12(%eax,%ecx,8), %xmm0");
679 asm volatile("sha1rnds4 $0x91, 0x12345678(%eax), %xmm0");
680 asm volatile("sha1rnds4 $0x91, 0x12345678(%ebp), %xmm0");
681 asm volatile("sha1rnds4 $0x91, 0x12345678(%ecx,%eax,1), %xmm0");
682 asm volatile("sha1rnds4 $0x91, 0x12345678(%ebp,%eax,1), %xmm0");
683 asm volatile("sha1rnds4 $0x91, 0x12345678(%eax,%ecx,1), %xmm0");
684 asm volatile("sha1rnds4 $0x91, 0x12345678(%eax,%ecx,8), %xmm0");
685
686 /* sha1nexte xmm2/m128, xmm1 */
687
688 asm volatile("sha1nexte %xmm1, %xmm0");
689 asm volatile("sha1nexte %xmm7, %xmm2");
690 asm volatile("sha1nexte (%eax), %xmm0");
691 asm volatile("sha1nexte (0x12345678), %xmm0");
692 asm volatile("sha1nexte (%eax), %xmm3");
693 asm volatile("sha1nexte (%ecx,%eax,1), %xmm0");
694 asm volatile("sha1nexte 0x12345678(,%eax,1), %xmm0");
695 asm volatile("sha1nexte (%eax,%ecx,1), %xmm0");
696 asm volatile("sha1nexte (%eax,%ecx,8), %xmm0");
697 asm volatile("sha1nexte 0x12(%eax), %xmm0");
698 asm volatile("sha1nexte 0x12(%ebp), %xmm0");
699 asm volatile("sha1nexte 0x12(%ecx,%eax,1), %xmm0");
700 asm volatile("sha1nexte 0x12(%ebp,%eax,1), %xmm0");
701 asm volatile("sha1nexte 0x12(%eax,%ecx,1), %xmm0");
702 asm volatile("sha1nexte 0x12(%eax,%ecx,8), %xmm0");
703 asm volatile("sha1nexte 0x12345678(%eax), %xmm0");
704 asm volatile("sha1nexte 0x12345678(%ebp), %xmm0");
705 asm volatile("sha1nexte 0x12345678(%ecx,%eax,1), %xmm0");
706 asm volatile("sha1nexte 0x12345678(%ebp,%eax,1), %xmm0");
707 asm volatile("sha1nexte 0x12345678(%eax,%ecx,1), %xmm0");
708 asm volatile("sha1nexte 0x12345678(%eax,%ecx,8), %xmm0");
709
710 /* sha1msg1 xmm2/m128, xmm1 */
711
712 asm volatile("sha1msg1 %xmm1, %xmm0");
713 asm volatile("sha1msg1 %xmm7, %xmm2");
714 asm volatile("sha1msg1 (%eax), %xmm0");
715 asm volatile("sha1msg1 (0x12345678), %xmm0");
716 asm volatile("sha1msg1 (%eax), %xmm3");
717 asm volatile("sha1msg1 (%ecx,%eax,1), %xmm0");
718 asm volatile("sha1msg1 0x12345678(,%eax,1), %xmm0");
719 asm volatile("sha1msg1 (%eax,%ecx,1), %xmm0");
720 asm volatile("sha1msg1 (%eax,%ecx,8), %xmm0");
721 asm volatile("sha1msg1 0x12(%eax), %xmm0");
722 asm volatile("sha1msg1 0x12(%ebp), %xmm0");
723 asm volatile("sha1msg1 0x12(%ecx,%eax,1), %xmm0");
724 asm volatile("sha1msg1 0x12(%ebp,%eax,1), %xmm0");
725 asm volatile("sha1msg1 0x12(%eax,%ecx,1), %xmm0");
726 asm volatile("sha1msg1 0x12(%eax,%ecx,8), %xmm0");
727 asm volatile("sha1msg1 0x12345678(%eax), %xmm0");
728 asm volatile("sha1msg1 0x12345678(%ebp), %xmm0");
729 asm volatile("sha1msg1 0x12345678(%ecx,%eax,1), %xmm0");
730 asm volatile("sha1msg1 0x12345678(%ebp,%eax,1), %xmm0");
731 asm volatile("sha1msg1 0x12345678(%eax,%ecx,1), %xmm0");
732 asm volatile("sha1msg1 0x12345678(%eax,%ecx,8), %xmm0");
733
734 /* sha1msg2 xmm2/m128, xmm1 */
735
736 asm volatile("sha1msg2 %xmm1, %xmm0");
737 asm volatile("sha1msg2 %xmm7, %xmm2");
738 asm volatile("sha1msg2 (%eax), %xmm0");
739 asm volatile("sha1msg2 (0x12345678), %xmm0");
740 asm volatile("sha1msg2 (%eax), %xmm3");
741 asm volatile("sha1msg2 (%ecx,%eax,1), %xmm0");
742 asm volatile("sha1msg2 0x12345678(,%eax,1), %xmm0");
743 asm volatile("sha1msg2 (%eax,%ecx,1), %xmm0");
744 asm volatile("sha1msg2 (%eax,%ecx,8), %xmm0");
745 asm volatile("sha1msg2 0x12(%eax), %xmm0");
746 asm volatile("sha1msg2 0x12(%ebp), %xmm0");
747 asm volatile("sha1msg2 0x12(%ecx,%eax,1), %xmm0");
748 asm volatile("sha1msg2 0x12(%ebp,%eax,1), %xmm0");
749 asm volatile("sha1msg2 0x12(%eax,%ecx,1), %xmm0");
750 asm volatile("sha1msg2 0x12(%eax,%ecx,8), %xmm0");
751 asm volatile("sha1msg2 0x12345678(%eax), %xmm0");
752 asm volatile("sha1msg2 0x12345678(%ebp), %xmm0");
753 asm volatile("sha1msg2 0x12345678(%ecx,%eax,1), %xmm0");
754 asm volatile("sha1msg2 0x12345678(%ebp,%eax,1), %xmm0");
755 asm volatile("sha1msg2 0x12345678(%eax,%ecx,1), %xmm0");
756 asm volatile("sha1msg2 0x12345678(%eax,%ecx,8), %xmm0");
757
758 /* sha256rnds2 <XMM0>, xmm2/m128, xmm1 */
759 /* Note sha256rnds2 has an implicit operand 'xmm0' */
760
761 asm volatile("sha256rnds2 %xmm4, %xmm1");
762 asm volatile("sha256rnds2 %xmm7, %xmm2");
763 asm volatile("sha256rnds2 (%eax), %xmm1");
764 asm volatile("sha256rnds2 (0x12345678), %xmm1");
765 asm volatile("sha256rnds2 (%eax), %xmm3");
766 asm volatile("sha256rnds2 (%ecx,%eax,1), %xmm1");
767 asm volatile("sha256rnds2 0x12345678(,%eax,1), %xmm1");
768 asm volatile("sha256rnds2 (%eax,%ecx,1), %xmm1");
769 asm volatile("sha256rnds2 (%eax,%ecx,8), %xmm1");
770 asm volatile("sha256rnds2 0x12(%eax), %xmm1");
771 asm volatile("sha256rnds2 0x12(%ebp), %xmm1");
772 asm volatile("sha256rnds2 0x12(%ecx,%eax,1), %xmm1");
773 asm volatile("sha256rnds2 0x12(%ebp,%eax,1), %xmm1");
774 asm volatile("sha256rnds2 0x12(%eax,%ecx,1), %xmm1");
775 asm volatile("sha256rnds2 0x12(%eax,%ecx,8), %xmm1");
776 asm volatile("sha256rnds2 0x12345678(%eax), %xmm1");
777 asm volatile("sha256rnds2 0x12345678(%ebp), %xmm1");
778 asm volatile("sha256rnds2 0x12345678(%ecx,%eax,1), %xmm1");
779 asm volatile("sha256rnds2 0x12345678(%ebp,%eax,1), %xmm1");
780 asm volatile("sha256rnds2 0x12345678(%eax,%ecx,1), %xmm1");
781 asm volatile("sha256rnds2 0x12345678(%eax,%ecx,8), %xmm1");
782
783 /* sha256msg1 xmm2/m128, xmm1 */
784
785 asm volatile("sha256msg1 %xmm1, %xmm0");
786 asm volatile("sha256msg1 %xmm7, %xmm2");
787 asm volatile("sha256msg1 (%eax), %xmm0");
788 asm volatile("sha256msg1 (0x12345678), %xmm0");
789 asm volatile("sha256msg1 (%eax), %xmm3");
790 asm volatile("sha256msg1 (%ecx,%eax,1), %xmm0");
791 asm volatile("sha256msg1 0x12345678(,%eax,1), %xmm0");
792 asm volatile("sha256msg1 (%eax,%ecx,1), %xmm0");
793 asm volatile("sha256msg1 (%eax,%ecx,8), %xmm0");
794 asm volatile("sha256msg1 0x12(%eax), %xmm0");
795 asm volatile("sha256msg1 0x12(%ebp), %xmm0");
796 asm volatile("sha256msg1 0x12(%ecx,%eax,1), %xmm0");
797 asm volatile("sha256msg1 0x12(%ebp,%eax,1), %xmm0");
798 asm volatile("sha256msg1 0x12(%eax,%ecx,1), %xmm0");
799 asm volatile("sha256msg1 0x12(%eax,%ecx,8), %xmm0");
800 asm volatile("sha256msg1 0x12345678(%eax), %xmm0");
801 asm volatile("sha256msg1 0x12345678(%ebp), %xmm0");
802 asm volatile("sha256msg1 0x12345678(%ecx,%eax,1), %xmm0");
803 asm volatile("sha256msg1 0x12345678(%ebp,%eax,1), %xmm0");
804 asm volatile("sha256msg1 0x12345678(%eax,%ecx,1), %xmm0");
805 asm volatile("sha256msg1 0x12345678(%eax,%ecx,8), %xmm0");
806
807 /* sha256msg2 xmm2/m128, xmm1 */
808
809 asm volatile("sha256msg2 %xmm1, %xmm0");
810 asm volatile("sha256msg2 %xmm7, %xmm2");
811 asm volatile("sha256msg2 (%eax), %xmm0");
812 asm volatile("sha256msg2 (0x12345678), %xmm0");
813 asm volatile("sha256msg2 (%eax), %xmm3");
814 asm volatile("sha256msg2 (%ecx,%eax,1), %xmm0");
815 asm volatile("sha256msg2 0x12345678(,%eax,1), %xmm0");
816 asm volatile("sha256msg2 (%eax,%ecx,1), %xmm0");
817 asm volatile("sha256msg2 (%eax,%ecx,8), %xmm0");
818 asm volatile("sha256msg2 0x12(%eax), %xmm0");
819 asm volatile("sha256msg2 0x12(%ebp), %xmm0");
820 asm volatile("sha256msg2 0x12(%ecx,%eax,1), %xmm0");
821 asm volatile("sha256msg2 0x12(%ebp,%eax,1), %xmm0");
822 asm volatile("sha256msg2 0x12(%eax,%ecx,1), %xmm0");
823 asm volatile("sha256msg2 0x12(%eax,%ecx,8), %xmm0");
824 asm volatile("sha256msg2 0x12345678(%eax), %xmm0");
825 asm volatile("sha256msg2 0x12345678(%ebp), %xmm0");
826 asm volatile("sha256msg2 0x12345678(%ecx,%eax,1), %xmm0");
827 asm volatile("sha256msg2 0x12345678(%ebp,%eax,1), %xmm0");
828 asm volatile("sha256msg2 0x12345678(%eax,%ecx,1), %xmm0");
829 asm volatile("sha256msg2 0x12345678(%eax,%ecx,8), %xmm0");
830
831 /* clflushopt m8 */
832
833 asm volatile("clflushopt (%eax)");
834 asm volatile("clflushopt (0x12345678)");
835 asm volatile("clflushopt 0x12345678(%eax,%ecx,8)");
836 /* Also check instructions in the same group encoding as clflushopt */
837 asm volatile("clflush (%eax)");
838 asm volatile("sfence");
839
840 /* clwb m8 */
841
842 asm volatile("clwb (%eax)");
843 asm volatile("clwb (0x12345678)");
844 asm volatile("clwb 0x12345678(%eax,%ecx,8)");
845 /* Also check instructions in the same group encoding as clwb */
846 asm volatile("xsaveopt (%eax)");
847 asm volatile("mfence");
848
849 /* xsavec mem */
850
851 asm volatile("xsavec (%eax)");
852 asm volatile("xsavec (0x12345678)");
853 asm volatile("xsavec 0x12345678(%eax,%ecx,8)");
854
855 /* xsaves mem */
856
857 asm volatile("xsaves (%eax)");
858 asm volatile("xsaves (0x12345678)");
859 asm volatile("xsaves 0x12345678(%eax,%ecx,8)");
860
861 /* xrstors mem */
862
863 asm volatile("xrstors (%eax)");
864 asm volatile("xrstors (0x12345678)");
865 asm volatile("xrstors 0x12345678(%eax,%ecx,8)");
866
867#endif /* #ifndef __x86_64__ */
868
869 /* pcommit */
870
871 asm volatile("pcommit");
872
873 /* Following line is a marker for the awk script - do not change */
874 asm volatile("rdtsc"); /* Stop here */
875
876 return 0;
877}
diff --git a/tools/perf/arch/x86/tests/insn-x86.c b/tools/perf/arch/x86/tests/insn-x86.c
new file mode 100644
index 000000000000..b6115dfd28f0
--- /dev/null
+++ b/tools/perf/arch/x86/tests/insn-x86.c
@@ -0,0 +1,185 @@
1#include <linux/types.h>
2
3#include "debug.h"
4#include "tests/tests.h"
5#include "arch-tests.h"
6
7#include "intel-pt-decoder/insn.h"
8#include "intel-pt-decoder/intel-pt-insn-decoder.h"
9
10struct test_data {
11 u8 data[MAX_INSN_SIZE];
12 int expected_length;
13 int expected_rel;
14 const char *expected_op_str;
15 const char *expected_branch_str;
16 const char *asm_rep;
17};
18
19struct test_data test_data_32[] = {
20#include "insn-x86-dat-32.c"
21 {{0x0f, 0x01, 0xee}, 3, 0, NULL, NULL, "0f 01 ee \trdpkru"},
22 {{0x0f, 0x01, 0xef}, 3, 0, NULL, NULL, "0f 01 ef \twrpkru"},
23 {{0}, 0, 0, NULL, NULL, NULL},
24};
25
26struct test_data test_data_64[] = {
27#include "insn-x86-dat-64.c"
28 {{0x0f, 0x01, 0xee}, 3, 0, NULL, NULL, "0f 01 ee \trdpkru"},
29 {{0x0f, 0x01, 0xef}, 3, 0, NULL, NULL, "0f 01 ef \twrpkru"},
30 {{0}, 0, 0, NULL, NULL, NULL},
31};
32
33static int get_op(const char *op_str)
34{
35 struct val_data {
36 const char *name;
37 int val;
38 } vals[] = {
39 {"other", INTEL_PT_OP_OTHER},
40 {"call", INTEL_PT_OP_CALL},
41 {"ret", INTEL_PT_OP_RET},
42 {"jcc", INTEL_PT_OP_JCC},
43 {"jmp", INTEL_PT_OP_JMP},
44 {"loop", INTEL_PT_OP_LOOP},
45 {"iret", INTEL_PT_OP_IRET},
46 {"int", INTEL_PT_OP_INT},
47 {"syscall", INTEL_PT_OP_SYSCALL},
48 {"sysret", INTEL_PT_OP_SYSRET},
49 {NULL, 0},
50 };
51 struct val_data *val;
52
53 if (!op_str || !strlen(op_str))
54 return 0;
55
56 for (val = vals; val->name; val++) {
57 if (!strcmp(val->name, op_str))
58 return val->val;
59 }
60
61 pr_debug("Failed to get op\n");
62
63 return -1;
64}
65
66static int get_branch(const char *branch_str)
67{
68 struct val_data {
69 const char *name;
70 int val;
71 } vals[] = {
72 {"no_branch", INTEL_PT_BR_NO_BRANCH},
73 {"indirect", INTEL_PT_BR_INDIRECT},
74 {"conditional", INTEL_PT_BR_CONDITIONAL},
75 {"unconditional", INTEL_PT_BR_UNCONDITIONAL},
76 {NULL, 0},
77 };
78 struct val_data *val;
79
80 if (!branch_str || !strlen(branch_str))
81 return 0;
82
83 for (val = vals; val->name; val++) {
84 if (!strcmp(val->name, branch_str))
85 return val->val;
86 }
87
88 pr_debug("Failed to get branch\n");
89
90 return -1;
91}
92
93static int test_data_item(struct test_data *dat, int x86_64)
94{
95 struct intel_pt_insn intel_pt_insn;
96 struct insn insn;
97 int op, branch;
98
99 insn_init(&insn, dat->data, MAX_INSN_SIZE, x86_64);
100 insn_get_length(&insn);
101
102 if (!insn_complete(&insn)) {
103 pr_debug("Failed to decode: %s\n", dat->asm_rep);
104 return -1;
105 }
106
107 if (insn.length != dat->expected_length) {
108 pr_debug("Failed to decode length (%d vs expected %d): %s\n",
109 insn.length, dat->expected_length, dat->asm_rep);
110 return -1;
111 }
112
113 op = get_op(dat->expected_op_str);
114 branch = get_branch(dat->expected_branch_str);
115
116 if (intel_pt_get_insn(dat->data, MAX_INSN_SIZE, x86_64, &intel_pt_insn)) {
117 pr_debug("Intel PT failed to decode: %s\n", dat->asm_rep);
118 return -1;
119 }
120
121 if ((int)intel_pt_insn.op != op) {
122 pr_debug("Failed to decode 'op' value (%d vs expected %d): %s\n",
123 intel_pt_insn.op, op, dat->asm_rep);
124 return -1;
125 }
126
127 if ((int)intel_pt_insn.branch != branch) {
128 pr_debug("Failed to decode 'branch' value (%d vs expected %d): %s\n",
129 intel_pt_insn.branch, branch, dat->asm_rep);
130 return -1;
131 }
132
133 if (intel_pt_insn.rel != dat->expected_rel) {
134 pr_debug("Failed to decode 'rel' value (%#x vs expected %#x): %s\n",
135 intel_pt_insn.rel, dat->expected_rel, dat->asm_rep);
136 return -1;
137 }
138
139 pr_debug("Decoded ok: %s\n", dat->asm_rep);
140
141 return 0;
142}
143
144static int test_data_set(struct test_data *dat_set, int x86_64)
145{
146 struct test_data *dat;
147 int ret = 0;
148
149 for (dat = dat_set; dat->expected_length; dat++) {
150 if (test_data_item(dat, x86_64))
151 ret = -1;
152 }
153
154 return ret;
155}
156
157/**
158 * test__insn_x86 - test x86 instruction decoder - new instructions.
159 *
160 * This function implements a test that decodes a selection of instructions and
161 * checks the results. The Intel PT function that further categorizes
162 * instructions (i.e. intel_pt_get_insn()) is also checked.
163 *
164 * The instructions are originally in insn-x86-dat-src.c which has been
165 * processed by scripts gen-insn-x86-dat.sh and gen-insn-x86-dat.awk to produce
166 * insn-x86-dat-32.c and insn-x86-dat-64.c which are included into this program.
167 * i.e. to add new instructions to the test, edit insn-x86-dat-src.c, run the
168 * gen-insn-x86-dat.sh script, make perf, and then run the test.
169 *
170 * If the test passes %0 is returned, otherwise %-1 is returned. Use the
171 * verbose (-v) option to see all the instructions and whether or not they
172 * decoded successfuly.
173 */
174int test__insn_x86(void)
175{
176 int ret = 0;
177
178 if (test_data_set(test_data_32, 0))
179 ret = -1;
180
181 if (test_data_set(test_data_64, 1))
182 ret = -1;
183
184 return ret;
185}
diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c
new file mode 100644
index 000000000000..d28c1b6a3b54
--- /dev/null
+++ b/tools/perf/arch/x86/tests/intel-cqm.c
@@ -0,0 +1,124 @@
1#include "tests/tests.h"
2#include "perf.h"
3#include "cloexec.h"
4#include "debug.h"
5#include "evlist.h"
6#include "evsel.h"
7#include "arch-tests.h"
8
9#include <sys/mman.h>
10#include <string.h>
11
12static pid_t spawn(void)
13{
14 pid_t pid;
15
16 pid = fork();
17 if (pid)
18 return pid;
19
20 while(1);
21 sleep(5);
22 return 0;
23}
24
25/*
26 * Create an event group that contains both a sampled hardware
27 * (cpu-cycles) and software (intel_cqm/llc_occupancy/) event. We then
28 * wait for the hardware perf counter to overflow and generate a PMI,
29 * which triggers an event read for both of the events in the group.
30 *
31 * Since reading Intel CQM event counters requires sending SMP IPIs, the
32 * CQM pmu needs to handle the above situation gracefully, and return
33 * the last read counter value to avoid triggering a WARN_ON_ONCE() in
34 * smp_call_function_many() caused by sending IPIs from NMI context.
35 */
36int test__intel_cqm_count_nmi_context(void)
37{
38 struct perf_evlist *evlist = NULL;
39 struct perf_evsel *evsel = NULL;
40 struct perf_event_attr pe;
41 int i, fd[2], flag, ret;
42 size_t mmap_len;
43 void *event;
44 pid_t pid;
45 int err = TEST_FAIL;
46
47 flag = perf_event_open_cloexec_flag();
48
49 evlist = perf_evlist__new();
50 if (!evlist) {
51 pr_debug("perf_evlist__new failed\n");
52 return TEST_FAIL;
53 }
54
55 ret = parse_events(evlist, "intel_cqm/llc_occupancy/", NULL);
56 if (ret) {
57 pr_debug("parse_events failed\n");
58 err = TEST_SKIP;
59 goto out;
60 }
61
62 evsel = perf_evlist__first(evlist);
63 if (!evsel) {
64 pr_debug("perf_evlist__first failed\n");
65 goto out;
66 }
67
68 memset(&pe, 0, sizeof(pe));
69 pe.size = sizeof(pe);
70
71 pe.type = PERF_TYPE_HARDWARE;
72 pe.config = PERF_COUNT_HW_CPU_CYCLES;
73 pe.read_format = PERF_FORMAT_GROUP;
74
75 pe.sample_period = 128;
76 pe.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_READ;
77
78 pid = spawn();
79
80 fd[0] = sys_perf_event_open(&pe, pid, -1, -1, flag);
81 if (fd[0] < 0) {
82 pr_debug("failed to open event\n");
83 goto out;
84 }
85
86 memset(&pe, 0, sizeof(pe));
87 pe.size = sizeof(pe);
88
89 pe.type = evsel->attr.type;
90 pe.config = evsel->attr.config;
91
92 fd[1] = sys_perf_event_open(&pe, pid, -1, fd[0], flag);
93 if (fd[1] < 0) {
94 pr_debug("failed to open event\n");
95 goto out;
96 }
97
98 /*
99 * Pick a power-of-two number of pages + 1 for the meta-data
100 * page (struct perf_event_mmap_page). See tools/perf/design.txt.
101 */
102 mmap_len = page_size * 65;
103
104 event = mmap(NULL, mmap_len, PROT_READ, MAP_SHARED, fd[0], 0);
105 if (event == (void *)(-1)) {
106 pr_debug("failed to mmap %d\n", errno);
107 goto out;
108 }
109
110 sleep(1);
111
112 err = TEST_OK;
113
114 munmap(event, mmap_len);
115
116 for (i = 0; i < 2; i++)
117 close(fd[i]);
118
119 kill(pid, SIGKILL);
120 wait(NULL);
121out:
122 perf_evlist__delete(evlist);
123 return err;
124}
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
index 5f49484f1abc..658cd200af74 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
@@ -9,7 +9,9 @@
9#include "thread_map.h" 9#include "thread_map.h"
10#include "cpumap.h" 10#include "cpumap.h"
11#include "tsc.h" 11#include "tsc.h"
12#include "tests.h" 12#include "tests/tests.h"
13
14#include "arch-tests.h"
13 15
14#define CHECK__(x) { \ 16#define CHECK__(x) { \
15 while ((x) < 0) { \ 17 while ((x) < 0) { \
diff --git a/tools/perf/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c
index d31f2c4d9f64..e7688214c7cf 100644
--- a/tools/perf/tests/rdpmc.c
+++ b/tools/perf/arch/x86/tests/rdpmc.c
@@ -5,10 +5,9 @@
5#include <linux/types.h> 5#include <linux/types.h>
6#include "perf.h" 6#include "perf.h"
7#include "debug.h" 7#include "debug.h"
8#include "tests.h" 8#include "tests/tests.h"
9#include "cloexec.h" 9#include "cloexec.h"
10 10#include "arch-tests.h"
11#if defined(__x86_64__) || defined(__i386__)
12 11
13static u64 rdpmc(unsigned int counter) 12static u64 rdpmc(unsigned int counter)
14{ 13{
@@ -173,5 +172,3 @@ int test__rdpmc(void)
173 172
174 return 0; 173 return 0;
175} 174}
176
177#endif
diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
index a08de0a35b83..9223c164e545 100644
--- a/tools/perf/arch/x86/util/dwarf-regs.c
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
@@ -21,55 +21,109 @@
21 */ 21 */
22 22
23#include <stddef.h> 23#include <stddef.h>
24#include <errno.h> /* for EINVAL */
25#include <string.h> /* for strcmp */
26#include <linux/ptrace.h> /* for struct pt_regs */
27#include <linux/kernel.h> /* for offsetof */
24#include <dwarf-regs.h> 28#include <dwarf-regs.h>
25 29
26/* 30/*
27 * Generic dwarf analysis helpers 31 * See arch/x86/kernel/ptrace.c.
32 * Different from it:
33 *
34 * - Since struct pt_regs is defined differently for user and kernel,
35 * but we want to use 'ax, bx' instead of 'rax, rbx' (which is struct
36 * field name of user's pt_regs), we make REG_OFFSET_NAME to accept
37 * both string name and reg field name.
38 *
39 * - Since accessing x86_32's pt_regs from x86_64 building is difficult
40 * and vise versa, we simply fill offset with -1, so
41 * get_arch_regstr() still works but regs_query_register_offset()
42 * returns error.
43 * The only inconvenience caused by it now is that we are not allowed
44 * to generate BPF prologue for a x86_64 kernel if perf is built for
45 * x86_32. This is really a rare usecase.
46 *
47 * - Order is different from kernel's ptrace.c for get_arch_regstr(). Use
48 * the order defined by dwarf.
28 */ 49 */
29 50
30#define X86_32_MAX_REGS 8 51struct pt_regs_offset {
31const char *x86_32_regs_table[X86_32_MAX_REGS] = { 52 const char *name;
32 "%ax", 53 int offset;
33 "%cx", 54};
34 "%dx", 55
35 "%bx", 56#define REG_OFFSET_END {.name = NULL, .offset = 0}
36 "$stack", /* Stack address instead of %sp */ 57
37 "%bp", 58#ifdef __x86_64__
38 "%si", 59# define REG_OFFSET_NAME_64(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)}
39 "%di", 60# define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = -1}
61#else
62# define REG_OFFSET_NAME_64(n, r) {.name = n, .offset = -1}
63# define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)}
64#endif
65
66static const struct pt_regs_offset x86_32_regoffset_table[] = {
67 REG_OFFSET_NAME_32("%ax", eax),
68 REG_OFFSET_NAME_32("%cx", ecx),
69 REG_OFFSET_NAME_32("%dx", edx),
70 REG_OFFSET_NAME_32("%bx", ebx),
71 REG_OFFSET_NAME_32("$stack", esp), /* Stack address instead of %sp */
72 REG_OFFSET_NAME_32("%bp", ebp),
73 REG_OFFSET_NAME_32("%si", esi),
74 REG_OFFSET_NAME_32("%di", edi),
75 REG_OFFSET_END,
40}; 76};
41 77
42#define X86_64_MAX_REGS 16 78static const struct pt_regs_offset x86_64_regoffset_table[] = {
43const char *x86_64_regs_table[X86_64_MAX_REGS] = { 79 REG_OFFSET_NAME_64("%ax", rax),
44 "%ax", 80 REG_OFFSET_NAME_64("%dx", rdx),
45 "%dx", 81 REG_OFFSET_NAME_64("%cx", rcx),
46 "%cx", 82 REG_OFFSET_NAME_64("%bx", rbx),
47 "%bx", 83 REG_OFFSET_NAME_64("%si", rsi),
48 "%si", 84 REG_OFFSET_NAME_64("%di", rdi),
49 "%di", 85 REG_OFFSET_NAME_64("%bp", rbp),
50 "%bp", 86 REG_OFFSET_NAME_64("%sp", rsp),
51 "%sp", 87 REG_OFFSET_NAME_64("%r8", r8),
52 "%r8", 88 REG_OFFSET_NAME_64("%r9", r9),
53 "%r9", 89 REG_OFFSET_NAME_64("%r10", r10),
54 "%r10", 90 REG_OFFSET_NAME_64("%r11", r11),
55 "%r11", 91 REG_OFFSET_NAME_64("%r12", r12),
56 "%r12", 92 REG_OFFSET_NAME_64("%r13", r13),
57 "%r13", 93 REG_OFFSET_NAME_64("%r14", r14),
58 "%r14", 94 REG_OFFSET_NAME_64("%r15", r15),
59 "%r15", 95 REG_OFFSET_END,
60}; 96};
61 97
62/* TODO: switching by dwarf address size */ 98/* TODO: switching by dwarf address size */
63#ifdef __x86_64__ 99#ifdef __x86_64__
64#define ARCH_MAX_REGS X86_64_MAX_REGS 100#define regoffset_table x86_64_regoffset_table
65#define arch_regs_table x86_64_regs_table
66#else 101#else
67#define ARCH_MAX_REGS X86_32_MAX_REGS 102#define regoffset_table x86_32_regoffset_table
68#define arch_regs_table x86_32_regs_table
69#endif 103#endif
70 104
105/* Minus 1 for the ending REG_OFFSET_END */
106#define ARCH_MAX_REGS ((sizeof(regoffset_table) / sizeof(regoffset_table[0])) - 1)
107
71/* Return architecture dependent register string (for kprobe-tracer) */ 108/* Return architecture dependent register string (for kprobe-tracer) */
72const char *get_arch_regstr(unsigned int n) 109const char *get_arch_regstr(unsigned int n)
73{ 110{
74 return (n < ARCH_MAX_REGS) ? arch_regs_table[n] : NULL; 111 return (n < ARCH_MAX_REGS) ? regoffset_table[n].name : NULL;
112}
113
114/* Reuse code from arch/x86/kernel/ptrace.c */
115/**
116 * regs_query_register_offset() - query register offset from its name
117 * @name: the name of a register
118 *
119 * regs_query_register_offset() returns the offset of a register in struct
120 * pt_regs from its name. If the name is invalid, this returns -EINVAL;
121 */
122int regs_query_register_offset(const char *name)
123{
124 const struct pt_regs_offset *roff;
125 for (roff = regoffset_table; roff->name != NULL; roff++)
126 if (!strcmp(roff->name, name))
127 return roff->offset;
128 return -EINVAL;
75} 129}
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index 2ca10d796c0b..b02af064f0f9 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -624,13 +624,49 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
624 * threads. 624 * threads.
625 */ 625 */
626 if (have_timing_info && !cpu_map__empty(cpus)) { 626 if (have_timing_info && !cpu_map__empty(cpus)) {
627 err = intel_pt_track_switches(evlist); 627 if (perf_can_record_switch_events()) {
628 if (err == -EPERM) 628 bool cpu_wide = !target__none(&opts->target) &&
629 pr_debug2("Unable to select sched:sched_switch\n"); 629 !target__has_task(&opts->target);
630 else if (err) 630
631 return err; 631 if (!cpu_wide && perf_can_record_cpu_wide()) {
632 else 632 struct perf_evsel *switch_evsel;
633 ptr->have_sched_switch = 1; 633
634 err = parse_events(evlist, "dummy:u", NULL);
635 if (err)
636 return err;
637
638 switch_evsel = perf_evlist__last(evlist);
639
640 switch_evsel->attr.freq = 0;
641 switch_evsel->attr.sample_period = 1;
642 switch_evsel->attr.context_switch = 1;
643
644 switch_evsel->system_wide = true;
645 switch_evsel->no_aux_samples = true;
646 switch_evsel->immediate = true;
647
648 perf_evsel__set_sample_bit(switch_evsel, TID);
649 perf_evsel__set_sample_bit(switch_evsel, TIME);
650 perf_evsel__set_sample_bit(switch_evsel, CPU);
651
652 opts->record_switch_events = false;
653 ptr->have_sched_switch = 3;
654 } else {
655 opts->record_switch_events = true;
656 if (cpu_wide)
657 ptr->have_sched_switch = 3;
658 else
659 ptr->have_sched_switch = 2;
660 }
661 } else {
662 err = intel_pt_track_switches(evlist);
663 if (err == -EPERM)
664 pr_debug2("Unable to select sched:sched_switch\n");
665 else if (err)
666 return err;
667 else
668 ptr->have_sched_switch = 1;
669 }
634 } 670 }
635 671
636 if (intel_pt_evsel) { 672 if (intel_pt_evsel) {
@@ -663,8 +699,11 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
663 tracking_evsel->attr.sample_period = 1; 699 tracking_evsel->attr.sample_period = 1;
664 700
665 /* In per-cpu case, always need the time of mmap events etc */ 701 /* In per-cpu case, always need the time of mmap events etc */
666 if (!cpu_map__empty(cpus)) 702 if (!cpu_map__empty(cpus)) {
667 perf_evsel__set_sample_bit(tracking_evsel, TIME); 703 perf_evsel__set_sample_bit(tracking_evsel, TIME);
704 /* And the CPU for switch events */
705 perf_evsel__set_sample_bit(tracking_evsel, CPU);
706 }
668 } 707 }
669 708
670 /* 709 /*
diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build
index 573e28896038..60bf11943047 100644
--- a/tools/perf/bench/Build
+++ b/tools/perf/bench/Build
@@ -1,6 +1,6 @@
1perf-y += sched-messaging.o 1perf-y += sched-messaging.o
2perf-y += sched-pipe.o 2perf-y += sched-pipe.o
3perf-y += mem-memcpy.o 3perf-y += mem-functions.o
4perf-y += futex-hash.o 4perf-y += futex-hash.o
5perf-y += futex-wake.o 5perf-y += futex-wake.o
6perf-y += futex-wake-parallel.o 6perf-y += futex-wake-parallel.o
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
new file mode 100644
index 000000000000..9419b944220f
--- /dev/null
+++ b/tools/perf/bench/mem-functions.c
@@ -0,0 +1,379 @@
1/*
2 * mem-memcpy.c
3 *
4 * Simple memcpy() and memset() benchmarks
5 *
6 * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
7 */
8
9#include "../perf.h"
10#include "../util/util.h"
11#include "../util/parse-options.h"
12#include "../util/header.h"
13#include "../util/cloexec.h"
14#include "bench.h"
15#include "mem-memcpy-arch.h"
16#include "mem-memset-arch.h"
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/time.h>
22#include <errno.h>
23
24#define K 1024
25
26static const char *size_str = "1MB";
27static const char *function_str = "all";
28static int nr_loops = 1;
29static bool use_cycles;
30static int cycles_fd;
31
32static const struct option options[] = {
33 OPT_STRING('s', "size", &size_str, "1MB",
34 "Specify the size of the memory buffers. "
35 "Available units: B, KB, MB, GB and TB (case insensitive)"),
36
37 OPT_STRING('f', "function", &function_str, "all",
38 "Specify the function to run, \"all\" runs all available functions, \"help\" lists them"),
39
40 OPT_INTEGER('l', "nr_loops", &nr_loops,
41 "Specify the number of loops to run. (default: 1)"),
42
43 OPT_BOOLEAN('c', "cycles", &use_cycles,
44 "Use a cycles event instead of gettimeofday() to measure performance"),
45
46 OPT_END()
47};
48
49typedef void *(*memcpy_t)(void *, const void *, size_t);
50typedef void *(*memset_t)(void *, int, size_t);
51
52struct function {
53 const char *name;
54 const char *desc;
55 union {
56 memcpy_t memcpy;
57 memset_t memset;
58 } fn;
59};
60
61static struct perf_event_attr cycle_attr = {
62 .type = PERF_TYPE_HARDWARE,
63 .config = PERF_COUNT_HW_CPU_CYCLES
64};
65
66static void init_cycles(void)
67{
68 cycles_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
69
70 if (cycles_fd < 0 && errno == ENOSYS)
71 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
72 else
73 BUG_ON(cycles_fd < 0);
74}
75
76static u64 get_cycles(void)
77{
78 int ret;
79 u64 clk;
80
81 ret = read(cycles_fd, &clk, sizeof(u64));
82 BUG_ON(ret != sizeof(u64));
83
84 return clk;
85}
86
87static double timeval2double(struct timeval *ts)
88{
89 return (double)ts->tv_sec + (double)ts->tv_usec / (double)1000000;
90}
91
92#define print_bps(x) do { \
93 if (x < K) \
94 printf(" %14lf bytes/sec\n", x); \
95 else if (x < K * K) \
96 printf(" %14lfd KB/sec\n", x / K); \
97 else if (x < K * K * K) \
98 printf(" %14lf MB/sec\n", x / K / K); \
99 else \
100 printf(" %14lf GB/sec\n", x / K / K / K); \
101 } while (0)
102
103struct bench_mem_info {
104 const struct function *functions;
105 u64 (*do_cycles)(const struct function *r, size_t size);
106 double (*do_gettimeofday)(const struct function *r, size_t size);
107 const char *const *usage;
108};
109
110static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total)
111{
112 const struct function *r = &info->functions[r_idx];
113 double result_bps = 0.0;
114 u64 result_cycles = 0;
115
116 printf("# function '%s' (%s)\n", r->name, r->desc);
117
118 if (bench_format == BENCH_FORMAT_DEFAULT)
119 printf("# Copying %s bytes ...\n\n", size_str);
120
121 if (use_cycles) {
122 result_cycles = info->do_cycles(r, size);
123 } else {
124 result_bps = info->do_gettimeofday(r, size);
125 }
126
127 switch (bench_format) {
128 case BENCH_FORMAT_DEFAULT:
129 if (use_cycles) {
130 printf(" %14lf cycles/byte\n", (double)result_cycles/size_total);
131 } else {
132 print_bps(result_bps);
133 }
134 break;
135
136 case BENCH_FORMAT_SIMPLE:
137 if (use_cycles) {
138 printf("%lf\n", (double)result_cycles/size_total);
139 } else {
140 printf("%lf\n", result_bps);
141 }
142 break;
143
144 default:
145 BUG_ON(1);
146 break;
147 }
148}
149
150static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
151{
152 int i;
153 size_t size;
154 double size_total;
155
156 argc = parse_options(argc, argv, options, info->usage, 0);
157
158 if (use_cycles)
159 init_cycles();
160
161 size = (size_t)perf_atoll((char *)size_str);
162 size_total = (double)size * nr_loops;
163
164 if ((s64)size <= 0) {
165 fprintf(stderr, "Invalid size:%s\n", size_str);
166 return 1;
167 }
168
169 if (!strncmp(function_str, "all", 3)) {
170 for (i = 0; info->functions[i].name; i++)
171 __bench_mem_function(info, i, size, size_total);
172 return 0;
173 }
174
175 for (i = 0; info->functions[i].name; i++) {
176 if (!strcmp(info->functions[i].name, function_str))
177 break;
178 }
179 if (!info->functions[i].name) {
180 if (strcmp(function_str, "help") && strcmp(function_str, "h"))
181 printf("Unknown function: %s\n", function_str);
182 printf("Available functions:\n");
183 for (i = 0; info->functions[i].name; i++) {
184 printf("\t%s ... %s\n",
185 info->functions[i].name, info->functions[i].desc);
186 }
187 return 1;
188 }
189
190 __bench_mem_function(info, i, size, size_total);
191
192 return 0;
193}
194
195static void memcpy_alloc_mem(void **dst, void **src, size_t size)
196{
197 *dst = zalloc(size);
198 if (!*dst)
199 die("memory allocation failed - maybe size is too large?\n");
200
201 *src = zalloc(size);
202 if (!*src)
203 die("memory allocation failed - maybe size is too large?\n");
204
205 /* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
206 memset(*src, 0, size);
207}
208
209static u64 do_memcpy_cycles(const struct function *r, size_t size)
210{
211 u64 cycle_start = 0ULL, cycle_end = 0ULL;
212 void *src = NULL, *dst = NULL;
213 memcpy_t fn = r->fn.memcpy;
214 int i;
215
216 memcpy_alloc_mem(&dst, &src, size);
217
218 /*
219 * We prefault the freshly allocated memory range here,
220 * to not measure page fault overhead:
221 */
222 fn(dst, src, size);
223
224 cycle_start = get_cycles();
225 for (i = 0; i < nr_loops; ++i)
226 fn(dst, src, size);
227 cycle_end = get_cycles();
228
229 free(src);
230 free(dst);
231 return cycle_end - cycle_start;
232}
233
234static double do_memcpy_gettimeofday(const struct function *r, size_t size)
235{
236 struct timeval tv_start, tv_end, tv_diff;
237 memcpy_t fn = r->fn.memcpy;
238 void *src = NULL, *dst = NULL;
239 int i;
240
241 memcpy_alloc_mem(&dst, &src, size);
242
243 /*
244 * We prefault the freshly allocated memory range here,
245 * to not measure page fault overhead:
246 */
247 fn(dst, src, size);
248
249 BUG_ON(gettimeofday(&tv_start, NULL));
250 for (i = 0; i < nr_loops; ++i)
251 fn(dst, src, size);
252 BUG_ON(gettimeofday(&tv_end, NULL));
253
254 timersub(&tv_end, &tv_start, &tv_diff);
255
256 free(src);
257 free(dst);
258
259 return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
260}
261
262struct function memcpy_functions[] = {
263 { .name = "default",
264 .desc = "Default memcpy() provided by glibc",
265 .fn.memcpy = memcpy },
266
267#ifdef HAVE_ARCH_X86_64_SUPPORT
268# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn},
269# include "mem-memcpy-x86-64-asm-def.h"
270# undef MEMCPY_FN
271#endif
272
273 { .name = NULL, }
274};
275
276static const char * const bench_mem_memcpy_usage[] = {
277 "perf bench mem memcpy <options>",
278 NULL
279};
280
281int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused)
282{
283 struct bench_mem_info info = {
284 .functions = memcpy_functions,
285 .do_cycles = do_memcpy_cycles,
286 .do_gettimeofday = do_memcpy_gettimeofday,
287 .usage = bench_mem_memcpy_usage,
288 };
289
290 return bench_mem_common(argc, argv, &info);
291}
292
293static void memset_alloc_mem(void **dst, size_t size)
294{
295 *dst = zalloc(size);
296 if (!*dst)
297 die("memory allocation failed - maybe size is too large?\n");
298}
299
300static u64 do_memset_cycles(const struct function *r, size_t size)
301{
302 u64 cycle_start = 0ULL, cycle_end = 0ULL;
303 memset_t fn = r->fn.memset;
304 void *dst = NULL;
305 int i;
306
307 memset_alloc_mem(&dst, size);
308
309 /*
310 * We prefault the freshly allocated memory range here,
311 * to not measure page fault overhead:
312 */
313 fn(dst, -1, size);
314
315 cycle_start = get_cycles();
316 for (i = 0; i < nr_loops; ++i)
317 fn(dst, i, size);
318 cycle_end = get_cycles();
319
320 free(dst);
321 return cycle_end - cycle_start;
322}
323
324static double do_memset_gettimeofday(const struct function *r, size_t size)
325{
326 struct timeval tv_start, tv_end, tv_diff;
327 memset_t fn = r->fn.memset;
328 void *dst = NULL;
329 int i;
330
331 memset_alloc_mem(&dst, size);
332
333 /*
334 * We prefault the freshly allocated memory range here,
335 * to not measure page fault overhead:
336 */
337 fn(dst, -1, size);
338
339 BUG_ON(gettimeofday(&tv_start, NULL));
340 for (i = 0; i < nr_loops; ++i)
341 fn(dst, i, size);
342 BUG_ON(gettimeofday(&tv_end, NULL));
343
344 timersub(&tv_end, &tv_start, &tv_diff);
345
346 free(dst);
347 return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
348}
349
350static const char * const bench_mem_memset_usage[] = {
351 "perf bench mem memset <options>",
352 NULL
353};
354
355static const struct function memset_functions[] = {
356 { .name = "default",
357 .desc = "Default memset() provided by glibc",
358 .fn.memset = memset },
359
360#ifdef HAVE_ARCH_X86_64_SUPPORT
361# define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
362# include "mem-memset-x86-64-asm-def.h"
363# undef MEMSET_FN
364#endif
365
366 { .name = NULL, }
367};
368
369int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused)
370{
371 struct bench_mem_info info = {
372 .functions = memset_functions,
373 .do_cycles = do_memset_cycles,
374 .do_gettimeofday = do_memset_gettimeofday,
375 .usage = bench_mem_memset_usage,
376 };
377
378 return bench_mem_common(argc, argv, &info);
379}
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
deleted file mode 100644
index d3dfb7936dcd..000000000000
--- a/tools/perf/bench/mem-memcpy.c
+++ /dev/null
@@ -1,434 +0,0 @@
1/*
2 * mem-memcpy.c
3 *
4 * memcpy: Simple memory copy in various ways
5 *
6 * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
7 */
8
9#include "../perf.h"
10#include "../util/util.h"
11#include "../util/parse-options.h"
12#include "../util/header.h"
13#include "../util/cloexec.h"
14#include "bench.h"
15#include "mem-memcpy-arch.h"
16#include "mem-memset-arch.h"
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/time.h>
22#include <errno.h>
23
24#define K 1024
25
26static const char *length_str = "1MB";
27static const char *routine = "default";
28static int iterations = 1;
29static bool use_cycle;
30static int cycle_fd;
31static bool only_prefault;
32static bool no_prefault;
33
34static const struct option options[] = {
35 OPT_STRING('l', "length", &length_str, "1MB",
36 "Specify length of memory to copy. "
37 "Available units: B, KB, MB, GB and TB (upper and lower)"),
38 OPT_STRING('r', "routine", &routine, "default",
39 "Specify routine to copy, \"all\" runs all available routines"),
40 OPT_INTEGER('i', "iterations", &iterations,
41 "repeat memcpy() invocation this number of times"),
42 OPT_BOOLEAN('c', "cycle", &use_cycle,
43 "Use cycles event instead of gettimeofday() for measuring"),
44 OPT_BOOLEAN('o', "only-prefault", &only_prefault,
45 "Show only the result with page faults before memcpy()"),
46 OPT_BOOLEAN('n', "no-prefault", &no_prefault,
47 "Show only the result without page faults before memcpy()"),
48 OPT_END()
49};
50
51typedef void *(*memcpy_t)(void *, const void *, size_t);
52typedef void *(*memset_t)(void *, int, size_t);
53
54struct routine {
55 const char *name;
56 const char *desc;
57 union {
58 memcpy_t memcpy;
59 memset_t memset;
60 } fn;
61};
62
63struct routine memcpy_routines[] = {
64 { .name = "default",
65 .desc = "Default memcpy() provided by glibc",
66 .fn.memcpy = memcpy },
67#ifdef HAVE_ARCH_X86_64_SUPPORT
68
69#define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn},
70#include "mem-memcpy-x86-64-asm-def.h"
71#undef MEMCPY_FN
72
73#endif
74
75 { NULL,
76 NULL,
77 {NULL} }
78};
79
80static const char * const bench_mem_memcpy_usage[] = {
81 "perf bench mem memcpy <options>",
82 NULL
83};
84
85static struct perf_event_attr cycle_attr = {
86 .type = PERF_TYPE_HARDWARE,
87 .config = PERF_COUNT_HW_CPU_CYCLES
88};
89
90static void init_cycle(void)
91{
92 cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1,
93 perf_event_open_cloexec_flag());
94
95 if (cycle_fd < 0 && errno == ENOSYS)
96 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
97 else
98 BUG_ON(cycle_fd < 0);
99}
100
101static u64 get_cycle(void)
102{
103 int ret;
104 u64 clk;
105
106 ret = read(cycle_fd, &clk, sizeof(u64));
107 BUG_ON(ret != sizeof(u64));
108
109 return clk;
110}
111
112static double timeval2double(struct timeval *ts)
113{
114 return (double)ts->tv_sec +
115 (double)ts->tv_usec / (double)1000000;
116}
117
118#define pf (no_prefault ? 0 : 1)
119
120#define print_bps(x) do { \
121 if (x < K) \
122 printf(" %14lf B/Sec", x); \
123 else if (x < K * K) \
124 printf(" %14lfd KB/Sec", x / K); \
125 else if (x < K * K * K) \
126 printf(" %14lf MB/Sec", x / K / K); \
127 else \
128 printf(" %14lf GB/Sec", x / K / K / K); \
129 } while (0)
130
131struct bench_mem_info {
132 const struct routine *routines;
133 u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault);
134 double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault);
135 const char *const *usage;
136};
137
138static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t len, double totallen)
139{
140 const struct routine *r = &info->routines[r_idx];
141 double result_bps[2];
142 u64 result_cycle[2];
143
144 result_cycle[0] = result_cycle[1] = 0ULL;
145 result_bps[0] = result_bps[1] = 0.0;
146
147 printf("Routine %s (%s)\n", r->name, r->desc);
148
149 if (bench_format == BENCH_FORMAT_DEFAULT)
150 printf("# Copying %s Bytes ...\n\n", length_str);
151
152 if (!only_prefault && !no_prefault) {
153 /* show both of results */
154 if (use_cycle) {
155 result_cycle[0] = info->do_cycle(r, len, false);
156 result_cycle[1] = info->do_cycle(r, len, true);
157 } else {
158 result_bps[0] = info->do_gettimeofday(r, len, false);
159 result_bps[1] = info->do_gettimeofday(r, len, true);
160 }
161 } else {
162 if (use_cycle)
163 result_cycle[pf] = info->do_cycle(r, len, only_prefault);
164 else
165 result_bps[pf] = info->do_gettimeofday(r, len, only_prefault);
166 }
167
168 switch (bench_format) {
169 case BENCH_FORMAT_DEFAULT:
170 if (!only_prefault && !no_prefault) {
171 if (use_cycle) {
172 printf(" %14lf Cycle/Byte\n",
173 (double)result_cycle[0]
174 / totallen);
175 printf(" %14lf Cycle/Byte (with prefault)\n",
176 (double)result_cycle[1]
177 / totallen);
178 } else {
179 print_bps(result_bps[0]);
180 printf("\n");
181 print_bps(result_bps[1]);
182 printf(" (with prefault)\n");
183 }
184 } else {
185 if (use_cycle) {
186 printf(" %14lf Cycle/Byte",
187 (double)result_cycle[pf]
188 / totallen);
189 } else
190 print_bps(result_bps[pf]);
191
192 printf("%s\n", only_prefault ? " (with prefault)" : "");
193 }
194 break;
195 case BENCH_FORMAT_SIMPLE:
196 if (!only_prefault && !no_prefault) {
197 if (use_cycle) {
198 printf("%lf %lf\n",
199 (double)result_cycle[0] / totallen,
200 (double)result_cycle[1] / totallen);
201 } else {
202 printf("%lf %lf\n",
203 result_bps[0], result_bps[1]);
204 }
205 } else {
206 if (use_cycle) {
207 printf("%lf\n", (double)result_cycle[pf]
208 / totallen);
209 } else
210 printf("%lf\n", result_bps[pf]);
211 }
212 break;
213 default:
214 /* reaching this means there's some disaster: */
215 die("unknown format: %d\n", bench_format);
216 break;
217 }
218}
219
220static int bench_mem_common(int argc, const char **argv,
221 const char *prefix __maybe_unused,
222 struct bench_mem_info *info)
223{
224 int i;
225 size_t len;
226 double totallen;
227
228 argc = parse_options(argc, argv, options,
229 info->usage, 0);
230
231 if (no_prefault && only_prefault) {
232 fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
233 return 1;
234 }
235
236 if (use_cycle)
237 init_cycle();
238
239 len = (size_t)perf_atoll((char *)length_str);
240 totallen = (double)len * iterations;
241
242 if ((s64)len <= 0) {
243 fprintf(stderr, "Invalid length:%s\n", length_str);
244 return 1;
245 }
246
247 /* same to without specifying either of prefault and no-prefault */
248 if (only_prefault && no_prefault)
249 only_prefault = no_prefault = false;
250
251 if (!strncmp(routine, "all", 3)) {
252 for (i = 0; info->routines[i].name; i++)
253 __bench_mem_routine(info, i, len, totallen);
254 return 0;
255 }
256
257 for (i = 0; info->routines[i].name; i++) {
258 if (!strcmp(info->routines[i].name, routine))
259 break;
260 }
261 if (!info->routines[i].name) {
262 printf("Unknown routine:%s\n", routine);
263 printf("Available routines...\n");
264 for (i = 0; info->routines[i].name; i++) {
265 printf("\t%s ... %s\n",
266 info->routines[i].name, info->routines[i].desc);
267 }
268 return 1;
269 }
270
271 __bench_mem_routine(info, i, len, totallen);
272
273 return 0;
274}
275
276static void memcpy_alloc_mem(void **dst, void **src, size_t length)
277{
278 *dst = zalloc(length);
279 if (!*dst)
280 die("memory allocation failed - maybe length is too large?\n");
281
282 *src = zalloc(length);
283 if (!*src)
284 die("memory allocation failed - maybe length is too large?\n");
285 /* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */
286 memset(*src, 0, length);
287}
288
289static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
290{
291 u64 cycle_start = 0ULL, cycle_end = 0ULL;
292 void *src = NULL, *dst = NULL;
293 memcpy_t fn = r->fn.memcpy;
294 int i;
295
296 memcpy_alloc_mem(&dst, &src, len);
297
298 if (prefault)
299 fn(dst, src, len);
300
301 cycle_start = get_cycle();
302 for (i = 0; i < iterations; ++i)
303 fn(dst, src, len);
304 cycle_end = get_cycle();
305
306 free(src);
307 free(dst);
308 return cycle_end - cycle_start;
309}
310
311static double do_memcpy_gettimeofday(const struct routine *r, size_t len,
312 bool prefault)
313{
314 struct timeval tv_start, tv_end, tv_diff;
315 memcpy_t fn = r->fn.memcpy;
316 void *src = NULL, *dst = NULL;
317 int i;
318
319 memcpy_alloc_mem(&dst, &src, len);
320
321 if (prefault)
322 fn(dst, src, len);
323
324 BUG_ON(gettimeofday(&tv_start, NULL));
325 for (i = 0; i < iterations; ++i)
326 fn(dst, src, len);
327 BUG_ON(gettimeofday(&tv_end, NULL));
328
329 timersub(&tv_end, &tv_start, &tv_diff);
330
331 free(src);
332 free(dst);
333 return (double)(((double)len * iterations) / timeval2double(&tv_diff));
334}
335
336int bench_mem_memcpy(int argc, const char **argv,
337 const char *prefix __maybe_unused)
338{
339 struct bench_mem_info info = {
340 .routines = memcpy_routines,
341 .do_cycle = do_memcpy_cycle,
342 .do_gettimeofday = do_memcpy_gettimeofday,
343 .usage = bench_mem_memcpy_usage,
344 };
345
346 return bench_mem_common(argc, argv, prefix, &info);
347}
348
349static void memset_alloc_mem(void **dst, size_t length)
350{
351 *dst = zalloc(length);
352 if (!*dst)
353 die("memory allocation failed - maybe length is too large?\n");
354}
355
356static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
357{
358 u64 cycle_start = 0ULL, cycle_end = 0ULL;
359 memset_t fn = r->fn.memset;
360 void *dst = NULL;
361 int i;
362
363 memset_alloc_mem(&dst, len);
364
365 if (prefault)
366 fn(dst, -1, len);
367
368 cycle_start = get_cycle();
369 for (i = 0; i < iterations; ++i)
370 fn(dst, i, len);
371 cycle_end = get_cycle();
372
373 free(dst);
374 return cycle_end - cycle_start;
375}
376
377static double do_memset_gettimeofday(const struct routine *r, size_t len,
378 bool prefault)
379{
380 struct timeval tv_start, tv_end, tv_diff;
381 memset_t fn = r->fn.memset;
382 void *dst = NULL;
383 int i;
384
385 memset_alloc_mem(&dst, len);
386
387 if (prefault)
388 fn(dst, -1, len);
389
390 BUG_ON(gettimeofday(&tv_start, NULL));
391 for (i = 0; i < iterations; ++i)
392 fn(dst, i, len);
393 BUG_ON(gettimeofday(&tv_end, NULL));
394
395 timersub(&tv_end, &tv_start, &tv_diff);
396
397 free(dst);
398 return (double)(((double)len * iterations) / timeval2double(&tv_diff));
399}
400
401static const char * const bench_mem_memset_usage[] = {
402 "perf bench mem memset <options>",
403 NULL
404};
405
406static const struct routine memset_routines[] = {
407 { .name ="default",
408 .desc = "Default memset() provided by glibc",
409 .fn.memset = memset },
410#ifdef HAVE_ARCH_X86_64_SUPPORT
411
412#define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
413#include "mem-memset-x86-64-asm-def.h"
414#undef MEMSET_FN
415
416#endif
417
418 { .name = NULL,
419 .desc = NULL,
420 .fn.memset = NULL }
421};
422
423int bench_mem_memset(int argc, const char **argv,
424 const char *prefix __maybe_unused)
425{
426 struct bench_mem_info info = {
427 .routines = memset_routines,
428 .do_cycle = do_memset_cycle,
429 .do_gettimeofday = do_memset_gettimeofday,
430 .usage = bench_mem_memset_usage,
431 };
432
433 return bench_mem_common(argc, argv, prefix, &info);
434}
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 870b7e665a20..492df2752a2d 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -164,8 +164,8 @@ static const struct option options[] = {
164 OPT_STRING('L', "mb_proc_locked", &p0.mb_proc_locked_str,"MB", "process serialized/locked memory access (MBs), <= process_memory"), 164 OPT_STRING('L', "mb_proc_locked", &p0.mb_proc_locked_str,"MB", "process serialized/locked memory access (MBs), <= process_memory"),
165 OPT_STRING('T', "mb_thread" , &p0.mb_thread_str, "MB", "thread memory (MBs)"), 165 OPT_STRING('T', "mb_thread" , &p0.mb_thread_str, "MB", "thread memory (MBs)"),
166 166
167 OPT_UINTEGER('l', "nr_loops" , &p0.nr_loops, "max number of loops to run"), 167 OPT_UINTEGER('l', "nr_loops" , &p0.nr_loops, "max number of loops to run (default: unlimited)"),
168 OPT_UINTEGER('s', "nr_secs" , &p0.nr_secs, "max number of seconds to run"), 168 OPT_UINTEGER('s', "nr_secs" , &p0.nr_secs, "max number of seconds to run (default: 5 secs)"),
169 OPT_UINTEGER('u', "usleep" , &p0.sleep_usecs, "usecs to sleep per loop iteration"), 169 OPT_UINTEGER('u', "usleep" , &p0.sleep_usecs, "usecs to sleep per loop iteration"),
170 170
171 OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via writes (can be mixed with -W)"), 171 OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via writes (can be mixed with -W)"),
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c
index d7f281c2828d..d4ff1b539cfd 100644
--- a/tools/perf/bench/sched-messaging.c
+++ b/tools/perf/bench/sched-messaging.c
@@ -33,7 +33,7 @@
33#define DATASIZE 100 33#define DATASIZE 100
34 34
35static bool use_pipes = false; 35static bool use_pipes = false;
36static unsigned int loops = 100; 36static unsigned int nr_loops = 100;
37static bool thread_mode = false; 37static bool thread_mode = false;
38static unsigned int num_groups = 10; 38static unsigned int num_groups = 10;
39 39
@@ -79,7 +79,7 @@ static void ready(int ready_out, int wakefd)
79 err(EXIT_FAILURE, "poll"); 79 err(EXIT_FAILURE, "poll");
80} 80}
81 81
82/* Sender sprays loops messages down each file descriptor */ 82/* Sender sprays nr_loops messages down each file descriptor */
83static void *sender(struct sender_context *ctx) 83static void *sender(struct sender_context *ctx)
84{ 84{
85 char data[DATASIZE]; 85 char data[DATASIZE];
@@ -88,7 +88,7 @@ static void *sender(struct sender_context *ctx)
88 ready(ctx->ready_out, ctx->wakefd); 88 ready(ctx->ready_out, ctx->wakefd);
89 89
90 /* Now pump to every receiver. */ 90 /* Now pump to every receiver. */
91 for (i = 0; i < loops; i++) { 91 for (i = 0; i < nr_loops; i++) {
92 for (j = 0; j < ctx->num_fds; j++) { 92 for (j = 0; j < ctx->num_fds; j++) {
93 int ret, done = 0; 93 int ret, done = 0;
94 94
@@ -213,7 +213,7 @@ static unsigned int group(pthread_t *pth,
213 /* Create the pipe between client and server */ 213 /* Create the pipe between client and server */
214 fdpair(fds); 214 fdpair(fds);
215 215
216 ctx->num_packets = num_fds * loops; 216 ctx->num_packets = num_fds * nr_loops;
217 ctx->in_fds[0] = fds[0]; 217 ctx->in_fds[0] = fds[0];
218 ctx->in_fds[1] = fds[1]; 218 ctx->in_fds[1] = fds[1];
219 ctx->ready_out = ready_out; 219 ctx->ready_out = ready_out;
@@ -250,7 +250,7 @@ static const struct option options[] = {
250 OPT_BOOLEAN('t', "thread", &thread_mode, 250 OPT_BOOLEAN('t', "thread", &thread_mode,
251 "Be multi thread instead of multi process"), 251 "Be multi thread instead of multi process"),
252 OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"), 252 OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"),
253 OPT_UINTEGER('l', "loop", &loops, "Specify number of loops"), 253 OPT_UINTEGER('l', "nr_loops", &nr_loops, "Specify the number of loops to run (default: 100)"),
254 OPT_END() 254 OPT_END()
255}; 255};
256 256
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 8edc205ff9a7..2bf9b3fd9e61 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -211,7 +211,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
211 } 211 }
212 212
213 if (!objdump_path) { 213 if (!objdump_path) {
214 ret = perf_session_env__lookup_objdump(&session->header.env); 214 ret = perf_env__lookup_objdump(&session->header.env);
215 if (ret) 215 if (ret)
216 goto out; 216 goto out;
217 } 217 }
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index f67934d46d40..b17aed36ca16 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -36,7 +36,7 @@ struct bench {
36#ifdef HAVE_LIBNUMA_SUPPORT 36#ifdef HAVE_LIBNUMA_SUPPORT
37static struct bench numa_benchmarks[] = { 37static struct bench numa_benchmarks[] = {
38 { "mem", "Benchmark for NUMA workloads", bench_numa }, 38 { "mem", "Benchmark for NUMA workloads", bench_numa },
39 { "all", "Test all NUMA benchmarks", NULL }, 39 { "all", "Run all NUMA benchmarks", NULL },
40 { NULL, NULL, NULL } 40 { NULL, NULL, NULL }
41}; 41};
42#endif 42#endif
@@ -44,14 +44,14 @@ static struct bench numa_benchmarks[] = {
44static struct bench sched_benchmarks[] = { 44static struct bench sched_benchmarks[] = {
45 { "messaging", "Benchmark for scheduling and IPC", bench_sched_messaging }, 45 { "messaging", "Benchmark for scheduling and IPC", bench_sched_messaging },
46 { "pipe", "Benchmark for pipe() between two processes", bench_sched_pipe }, 46 { "pipe", "Benchmark for pipe() between two processes", bench_sched_pipe },
47 { "all", "Test all scheduler benchmarks", NULL }, 47 { "all", "Run all scheduler benchmarks", NULL },
48 { NULL, NULL, NULL } 48 { NULL, NULL, NULL }
49}; 49};
50 50
51static struct bench mem_benchmarks[] = { 51static struct bench mem_benchmarks[] = {
52 { "memcpy", "Benchmark for memcpy()", bench_mem_memcpy }, 52 { "memcpy", "Benchmark for memcpy() functions", bench_mem_memcpy },
53 { "memset", "Benchmark for memset() tests", bench_mem_memset }, 53 { "memset", "Benchmark for memset() functions", bench_mem_memset },
54 { "all", "Test all memory benchmarks", NULL }, 54 { "all", "Run all memory access benchmarks", NULL },
55 { NULL, NULL, NULL } 55 { NULL, NULL, NULL }
56}; 56};
57 57
@@ -62,7 +62,7 @@ static struct bench futex_benchmarks[] = {
62 { "requeue", "Benchmark for futex requeue calls", bench_futex_requeue }, 62 { "requeue", "Benchmark for futex requeue calls", bench_futex_requeue },
63 /* pi-futexes */ 63 /* pi-futexes */
64 { "lock-pi", "Benchmark for futex lock_pi calls", bench_futex_lock_pi }, 64 { "lock-pi", "Benchmark for futex lock_pi calls", bench_futex_lock_pi },
65 { "all", "Test all futex benchmarks", NULL }, 65 { "all", "Run all futex benchmarks", NULL },
66 { NULL, NULL, NULL } 66 { NULL, NULL, NULL }
67}; 67};
68 68
@@ -110,7 +110,7 @@ int bench_format = BENCH_FORMAT_DEFAULT;
110unsigned int bench_repeat = 10; /* default number of times to repeat the run */ 110unsigned int bench_repeat = 10; /* default number of times to repeat the run */
111 111
112static const struct option bench_options[] = { 112static const struct option bench_options[] = {
113 OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"), 113 OPT_STRING('f', "format", &bench_format_str, "default|simple", "Specify the output formatting style"),
114 OPT_UINTEGER('r', "repeat", &bench_repeat, "Specify amount of times to repeat the run"), 114 OPT_UINTEGER('r', "repeat", &bench_repeat, "Specify amount of times to repeat the run"),
115 OPT_END() 115 OPT_END()
116}; 116};
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index 695ec5a50cf2..f4d62510acbb 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -61,8 +61,8 @@ int cmd_evlist(int argc, const char **argv, const char *prefix __maybe_unused)
61 usage_with_options(evlist_usage, options); 61 usage_with_options(evlist_usage, options);
62 62
63 if (details.event_group && (details.verbose || details.freq)) { 63 if (details.event_group && (details.verbose || details.freq)) {
64 pr_err("--group option is not compatible with other options\n"); 64 usage_with_options_msg(evlist_usage, options,
65 usage_with_options(evlist_usage, options); 65 "--group option is not compatible with other options\n");
66 } 66 }
67 67
68 return __cmd_evlist(input_name, &details); 68 return __cmd_evlist(input_name, &details);
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 36486eade1ef..a7d588bf3cdd 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -463,7 +463,7 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
463 builtin_help_subcommands, builtin_help_usage, 0); 463 builtin_help_subcommands, builtin_help_usage, 0);
464 464
465 if (show_all) { 465 if (show_all) {
466 printf("\n usage: %s\n\n", perf_usage_string); 466 printf("\n Usage: %s\n\n", perf_usage_string);
467 list_commands("perf commands", &main_cmds, &other_cmds); 467 list_commands("perf commands", &main_cmds, &other_cmds);
468 printf(" %s\n\n", perf_more_info_string); 468 printf(" %s\n\n", perf_more_info_string);
469 return 0; 469 return 0;
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index f62c49b35be0..0a945d2e8ca5 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -28,9 +28,11 @@ struct perf_inject {
28 bool build_ids; 28 bool build_ids;
29 bool sched_stat; 29 bool sched_stat;
30 bool have_auxtrace; 30 bool have_auxtrace;
31 bool strip;
31 const char *input_name; 32 const char *input_name;
32 struct perf_data_file output; 33 struct perf_data_file output;
33 u64 bytes_written; 34 u64 bytes_written;
35 u64 aux_id;
34 struct list_head samples; 36 struct list_head samples;
35 struct itrace_synth_opts itrace_synth_opts; 37 struct itrace_synth_opts itrace_synth_opts;
36}; 38};
@@ -176,6 +178,27 @@ static int perf_event__repipe(struct perf_tool *tool,
176 return perf_event__repipe_synth(tool, event); 178 return perf_event__repipe_synth(tool, event);
177} 179}
178 180
181static int perf_event__drop(struct perf_tool *tool __maybe_unused,
182 union perf_event *event __maybe_unused,
183 struct perf_sample *sample __maybe_unused,
184 struct machine *machine __maybe_unused)
185{
186 return 0;
187}
188
189static int perf_event__drop_aux(struct perf_tool *tool,
190 union perf_event *event __maybe_unused,
191 struct perf_sample *sample,
192 struct machine *machine __maybe_unused)
193{
194 struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
195
196 if (!inject->aux_id)
197 inject->aux_id = sample->id;
198
199 return 0;
200}
201
179typedef int (*inject_handler)(struct perf_tool *tool, 202typedef int (*inject_handler)(struct perf_tool *tool,
180 union perf_event *event, 203 union perf_event *event,
181 struct perf_sample *sample, 204 struct perf_sample *sample,
@@ -466,6 +489,78 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel,
466 return 0; 489 return 0;
467} 490}
468 491
492static int drop_sample(struct perf_tool *tool __maybe_unused,
493 union perf_event *event __maybe_unused,
494 struct perf_sample *sample __maybe_unused,
495 struct perf_evsel *evsel __maybe_unused,
496 struct machine *machine __maybe_unused)
497{
498 return 0;
499}
500
501static void strip_init(struct perf_inject *inject)
502{
503 struct perf_evlist *evlist = inject->session->evlist;
504 struct perf_evsel *evsel;
505
506 inject->tool.context_switch = perf_event__drop;
507
508 evlist__for_each(evlist, evsel)
509 evsel->handler = drop_sample;
510}
511
512static bool has_tracking(struct perf_evsel *evsel)
513{
514 return evsel->attr.mmap || evsel->attr.mmap2 || evsel->attr.comm ||
515 evsel->attr.task;
516}
517
518#define COMPAT_MASK (PERF_SAMPLE_ID | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \
519 PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_IDENTIFIER)
520
521/*
522 * In order that the perf.data file is parsable, tracking events like MMAP need
523 * their selected event to exist, except if there is only 1 selected event left
524 * and it has a compatible sample type.
525 */
526static bool ok_to_remove(struct perf_evlist *evlist,
527 struct perf_evsel *evsel_to_remove)
528{
529 struct perf_evsel *evsel;
530 int cnt = 0;
531 bool ok = false;
532
533 if (!has_tracking(evsel_to_remove))
534 return true;
535
536 evlist__for_each(evlist, evsel) {
537 if (evsel->handler != drop_sample) {
538 cnt += 1;
539 if ((evsel->attr.sample_type & COMPAT_MASK) ==
540 (evsel_to_remove->attr.sample_type & COMPAT_MASK))
541 ok = true;
542 }
543 }
544
545 return ok && cnt == 1;
546}
547
548static void strip_fini(struct perf_inject *inject)
549{
550 struct perf_evlist *evlist = inject->session->evlist;
551 struct perf_evsel *evsel, *tmp;
552
553 /* Remove non-synthesized evsels if possible */
554 evlist__for_each_safe(evlist, tmp, evsel) {
555 if (evsel->handler == drop_sample &&
556 ok_to_remove(evlist, evsel)) {
557 pr_debug("Deleting %s\n", perf_evsel__name(evsel));
558 perf_evlist__remove(evlist, evsel);
559 perf_evsel__delete(evsel);
560 }
561 }
562}
563
469static int __cmd_inject(struct perf_inject *inject) 564static int __cmd_inject(struct perf_inject *inject)
470{ 565{
471 int ret = -EINVAL; 566 int ret = -EINVAL;
@@ -512,10 +607,14 @@ static int __cmd_inject(struct perf_inject *inject)
512 inject->tool.id_index = perf_event__repipe_id_index; 607 inject->tool.id_index = perf_event__repipe_id_index;
513 inject->tool.auxtrace_info = perf_event__process_auxtrace_info; 608 inject->tool.auxtrace_info = perf_event__process_auxtrace_info;
514 inject->tool.auxtrace = perf_event__process_auxtrace; 609 inject->tool.auxtrace = perf_event__process_auxtrace;
610 inject->tool.aux = perf_event__drop_aux;
611 inject->tool.itrace_start = perf_event__drop_aux,
515 inject->tool.ordered_events = true; 612 inject->tool.ordered_events = true;
516 inject->tool.ordering_requires_timestamps = true; 613 inject->tool.ordering_requires_timestamps = true;
517 /* Allow space in the header for new attributes */ 614 /* Allow space in the header for new attributes */
518 output_data_offset = 4096; 615 output_data_offset = 4096;
616 if (inject->strip)
617 strip_init(inject);
519 } 618 }
520 619
521 if (!inject->itrace_synth_opts.set) 620 if (!inject->itrace_synth_opts.set)
@@ -535,11 +634,28 @@ static int __cmd_inject(struct perf_inject *inject)
535 } 634 }
536 /* 635 /*
537 * The AUX areas have been removed and replaced with 636 * The AUX areas have been removed and replaced with
538 * synthesized hardware events, so clear the feature flag. 637 * synthesized hardware events, so clear the feature flag and
638 * remove the evsel.
539 */ 639 */
540 if (inject->itrace_synth_opts.set) 640 if (inject->itrace_synth_opts.set) {
641 struct perf_evsel *evsel;
642
541 perf_header__clear_feat(&session->header, 643 perf_header__clear_feat(&session->header,
542 HEADER_AUXTRACE); 644 HEADER_AUXTRACE);
645 if (inject->itrace_synth_opts.last_branch)
646 perf_header__set_feat(&session->header,
647 HEADER_BRANCH_STACK);
648 evsel = perf_evlist__id2evsel_strict(session->evlist,
649 inject->aux_id);
650 if (evsel) {
651 pr_debug("Deleting %s\n",
652 perf_evsel__name(evsel));
653 perf_evlist__remove(session->evlist, evsel);
654 perf_evsel__delete(evsel);
655 }
656 if (inject->strip)
657 strip_fini(inject);
658 }
543 session->header.data_offset = output_data_offset; 659 session->header.data_offset = output_data_offset;
544 session->header.data_size = inject->bytes_written; 660 session->header.data_size = inject->bytes_written;
545 perf_session__write_header(session, session->evlist, fd, true); 661 perf_session__write_header(session, session->evlist, fd, true);
@@ -604,6 +720,8 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
604 OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts, 720 OPT_CALLBACK_OPTARG(0, "itrace", &inject.itrace_synth_opts,
605 NULL, "opts", "Instruction Tracing options", 721 NULL, "opts", "Instruction Tracing options",
606 itrace_parse_synth_opts), 722 itrace_parse_synth_opts),
723 OPT_BOOLEAN(0, "strip", &inject.strip,
724 "strip non-synthesized events (use with --itrace)"),
607 OPT_END() 725 OPT_END()
608 }; 726 };
609 const char * const inject_usage[] = { 727 const char * const inject_usage[] = {
@@ -619,6 +737,11 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
619 if (argc) 737 if (argc)
620 usage_with_options(inject_usage, options); 738 usage_with_options(inject_usage, options);
621 739
740 if (inject.strip && !inject.itrace_synth_opts.set) {
741 pr_err("--strip option requires --itrace option\n");
742 return -1;
743 }
744
622 if (perf_data_file__open(&inject.output)) { 745 if (perf_data_file__open(&inject.output)) {
623 perror("failed to create output file"); 746 perror("failed to create output file");
624 return -1; 747 return -1;
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 23b1faaaa4cc..93ce665f976f 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -329,7 +329,7 @@ static int build_alloc_func_list(void)
329 return -EINVAL; 329 return -EINVAL;
330 } 330 }
331 331
332 kernel_map = machine->vmlinux_maps[MAP__FUNCTION]; 332 kernel_map = machine__kernel_map(machine);
333 if (map__load(kernel_map, NULL) < 0) { 333 if (map__load(kernel_map, NULL) < 0) {
334 pr_err("cannot load kernel map\n"); 334 pr_err("cannot load kernel map\n");
335 return -ENOENT; 335 return -ENOENT;
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index fc1cffb1b7a2..dd94b4ca2213 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -13,7 +13,6 @@
13#include "util/parse-options.h" 13#include "util/parse-options.h"
14#include "util/trace-event.h" 14#include "util/trace-event.h"
15#include "util/debug.h" 15#include "util/debug.h"
16#include <api/fs/debugfs.h>
17#include "util/tool.h" 16#include "util/tool.h"
18#include "util/stat.h" 17#include "util/stat.h"
19#include "util/top.h" 18#include "util/top.h"
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index af5bd0514108..bf679e2c978b 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -36,7 +36,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
36 36
37 setup_pager(); 37 setup_pager();
38 38
39 if (!raw_dump) 39 if (!raw_dump && pager_in_use())
40 printf("\nList of pre-defined events (to be used in -e):\n\n"); 40 printf("\nList of pre-defined events (to be used in -e):\n\n");
41 41
42 if (argc == 0) { 42 if (argc == 0) {
@@ -45,6 +45,8 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
45 } 45 }
46 46
47 for (i = 0; i < argc; ++i) { 47 for (i = 0; i < argc; ++i) {
48 char *sep, *s;
49
48 if (strcmp(argv[i], "tracepoint") == 0) 50 if (strcmp(argv[i], "tracepoint") == 0)
49 print_tracepoint_events(NULL, NULL, raw_dump); 51 print_tracepoint_events(NULL, NULL, raw_dump);
50 else if (strcmp(argv[i], "hw") == 0 || 52 else if (strcmp(argv[i], "hw") == 0 ||
@@ -60,8 +62,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
60 print_hwcache_events(NULL, raw_dump); 62 print_hwcache_events(NULL, raw_dump);
61 else if (strcmp(argv[i], "pmu") == 0) 63 else if (strcmp(argv[i], "pmu") == 0)
62 print_pmu_events(NULL, raw_dump); 64 print_pmu_events(NULL, raw_dump);
63 else { 65 else if ((sep = strchr(argv[i], ':')) != NULL) {
64 char *sep = strchr(argv[i], ':'), *s;
65 int sep_idx; 66 int sep_idx;
66 67
67 if (sep == NULL) { 68 if (sep == NULL) {
@@ -76,6 +77,19 @@ int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
76 s[sep_idx] = '\0'; 77 s[sep_idx] = '\0';
77 print_tracepoint_events(s, s + sep_idx + 1, raw_dump); 78 print_tracepoint_events(s, s + sep_idx + 1, raw_dump);
78 free(s); 79 free(s);
80 } else {
81 if (asprintf(&s, "*%s*", argv[i]) < 0) {
82 printf("Critical: Not enough memory! Trying to continue...\n");
83 continue;
84 }
85 print_symbol_events(s, PERF_TYPE_HARDWARE,
86 event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump);
87 print_symbol_events(s, PERF_TYPE_SOFTWARE,
88 event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump);
89 print_hwcache_events(s, raw_dump);
90 print_pmu_events(s, raw_dump);
91 print_tracepoint_events(NULL, s, raw_dump);
92 free(s);
79 } 93 }
80 } 94 }
81 return 0; 95 return 0;
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index b81cec33b4b2..132afc97676c 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -37,10 +37,10 @@
37#include "util/strfilter.h" 37#include "util/strfilter.h"
38#include "util/symbol.h" 38#include "util/symbol.h"
39#include "util/debug.h" 39#include "util/debug.h"
40#include <api/fs/debugfs.h>
41#include "util/parse-options.h" 40#include "util/parse-options.h"
42#include "util/probe-finder.h" 41#include "util/probe-finder.h"
43#include "util/probe-event.h" 42#include "util/probe-event.h"
43#include "util/probe-file.h"
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 "!_*"
@@ -182,10 +182,8 @@ static int opt_set_target(const struct option *opt, const char *str,
182 if (str) { 182 if (str) {
183 if (!strcmp(opt->long_name, "exec")) 183 if (!strcmp(opt->long_name, "exec"))
184 params.uprobes = true; 184 params.uprobes = true;
185#ifdef HAVE_DWARF_SUPPORT
186 else if (!strcmp(opt->long_name, "module")) 185 else if (!strcmp(opt->long_name, "module"))
187 params.uprobes = false; 186 params.uprobes = false;
188#endif
189 else 187 else
190 return ret; 188 return ret;
191 189
@@ -311,6 +309,119 @@ static void pr_err_with_code(const char *msg, int err)
311 pr_err("\n"); 309 pr_err("\n");
312} 310}
313 311
312static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs)
313{
314 int ret;
315 int i, k;
316 const char *event = NULL, *group = NULL;
317
318 ret = init_probe_symbol_maps(pevs->uprobes);
319 if (ret < 0)
320 return ret;
321
322 ret = convert_perf_probe_events(pevs, npevs);
323 if (ret < 0)
324 goto out_cleanup;
325
326 ret = apply_perf_probe_events(pevs, npevs);
327 if (ret < 0)
328 goto out_cleanup;
329
330 for (i = k = 0; i < npevs; i++)
331 k += pevs[i].ntevs;
332
333 pr_info("Added new event%s\n", (k > 1) ? "s:" : ":");
334 for (i = 0; i < npevs; i++) {
335 struct perf_probe_event *pev = &pevs[i];
336
337 for (k = 0; k < pev->ntevs; k++) {
338 struct probe_trace_event *tev = &pev->tevs[k];
339
340 /* We use tev's name for showing new events */
341 show_perf_probe_event(tev->group, tev->event, pev,
342 tev->point.module, false);
343
344 /* Save the last valid name */
345 event = tev->event;
346 group = tev->group;
347 }
348 }
349
350 /* Note that it is possible to skip all events because of blacklist */
351 if (event) {
352 /* Show how to use the event. */
353 pr_info("\nYou can now use it in all perf tools, such as:\n\n");
354 pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
355 }
356
357out_cleanup:
358 cleanup_perf_probe_events(pevs, npevs);
359 exit_probe_symbol_maps();
360 return ret;
361}
362
363static int perf_del_probe_events(struct strfilter *filter)
364{
365 int ret, ret2, ufd = -1, kfd = -1;
366 char *str = strfilter__string(filter);
367 struct strlist *klist = NULL, *ulist = NULL;
368 struct str_node *ent;
369
370 if (!str)
371 return -EINVAL;
372
373 pr_debug("Delete filter: \'%s\'\n", str);
374
375 /* Get current event names */
376 ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
377 if (ret < 0)
378 goto out;
379
380 klist = strlist__new(NULL, NULL);
381 ulist = strlist__new(NULL, NULL);
382 if (!klist || !ulist) {
383 ret = -ENOMEM;
384 goto out;
385 }
386
387 ret = probe_file__get_events(kfd, filter, klist);
388 if (ret == 0) {
389 strlist__for_each(ent, klist)
390 pr_info("Removed event: %s\n", ent->s);
391
392 ret = probe_file__del_strlist(kfd, klist);
393 if (ret < 0)
394 goto error;
395 }
396
397 ret2 = probe_file__get_events(ufd, filter, ulist);
398 if (ret2 == 0) {
399 strlist__for_each(ent, ulist)
400 pr_info("Removed event: %s\n", ent->s);
401
402 ret2 = probe_file__del_strlist(ufd, ulist);
403 if (ret2 < 0)
404 goto error;
405 }
406
407 if (ret == -ENOENT && ret2 == -ENOENT)
408 pr_debug("\"%s\" does not hit any event.\n", str);
409 /* Note that this is silently ignored */
410 ret = 0;
411
412error:
413 if (kfd >= 0)
414 close(kfd);
415 if (ufd >= 0)
416 close(ufd);
417out:
418 strlist__delete(klist);
419 strlist__delete(ulist);
420 free(str);
421
422 return ret;
423}
424
314static int 425static int
315__cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) 426__cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
316{ 427{
@@ -377,9 +488,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
377 "file", "vmlinux pathname"), 488 "file", "vmlinux pathname"),
378 OPT_STRING('s', "source", &symbol_conf.source_prefix, 489 OPT_STRING('s', "source", &symbol_conf.source_prefix,
379 "directory", "path to kernel source"), 490 "directory", "path to kernel source"),
380 OPT_CALLBACK('m', "module", NULL, "modname|path",
381 "target module name (for online) or path (for offline)",
382 opt_set_target),
383 OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines, 491 OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines,
384 "Don't search inlined functions"), 492 "Don't search inlined functions"),
385#endif 493#endif
@@ -396,6 +504,9 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
396 opt_set_filter), 504 opt_set_filter),
397 OPT_CALLBACK('x', "exec", NULL, "executable|path", 505 OPT_CALLBACK('x', "exec", NULL, "executable|path",
398 "target executable name or path", opt_set_target), 506 "target executable name or path", opt_set_target),
507 OPT_CALLBACK('m', "module", NULL, "modname|path",
508 "target module name (for online) or path (for offline)",
509 opt_set_target),
399 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 510 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
400 "Enable symbol demangling"), 511 "Enable symbol demangling"),
401 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, 512 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
@@ -417,12 +528,12 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
417 PARSE_OPT_STOP_AT_NON_OPTION); 528 PARSE_OPT_STOP_AT_NON_OPTION);
418 if (argc > 0) { 529 if (argc > 0) {
419 if (strcmp(argv[0], "-") == 0) { 530 if (strcmp(argv[0], "-") == 0) {
420 pr_warning(" Error: '-' is not supported.\n"); 531 usage_with_options_msg(probe_usage, options,
421 usage_with_options(probe_usage, options); 532 "'-' is not supported.\n");
422 } 533 }
423 if (params.command && params.command != 'a') { 534 if (params.command && params.command != 'a') {
424 pr_warning(" Error: another command except --add is set.\n"); 535 usage_with_options_msg(probe_usage, options,
425 usage_with_options(probe_usage, options); 536 "another command except --add is set.\n");
426 } 537 }
427 ret = parse_probe_event_argv(argc, argv); 538 ret = parse_probe_event_argv(argc, argv);
428 if (ret < 0) { 539 if (ret < 0) {
@@ -451,8 +562,10 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
451 switch (params.command) { 562 switch (params.command) {
452 case 'l': 563 case 'l':
453 if (params.uprobes) { 564 if (params.uprobes) {
454 pr_warning(" Error: Don't use --list with --exec.\n"); 565 pr_err(" Error: Don't use --list with --exec.\n");
455 usage_with_options(probe_usage, options); 566 parse_options_usage(probe_usage, options, "l", true);
567 parse_options_usage(NULL, options, "x", true);
568 return -EINVAL;
456 } 569 }
457 ret = show_perf_probe_events(params.filter); 570 ret = show_perf_probe_events(params.filter);
458 if (ret < 0) 571 if (ret < 0)
@@ -483,7 +596,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
483 return ret; 596 return ret;
484#endif 597#endif
485 case 'd': 598 case 'd':
486 ret = del_perf_probe_events(params.filter); 599 ret = perf_del_probe_events(params.filter);
487 if (ret < 0) { 600 if (ret < 0) {
488 pr_err_with_code(" Error: Failed to delete events.", ret); 601 pr_err_with_code(" Error: Failed to delete events.", ret);
489 return ret; 602 return ret;
@@ -492,11 +605,13 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
492 case 'a': 605 case 'a':
493 /* Ensure the last given target is used */ 606 /* Ensure the last given target is used */
494 if (params.target && !params.target_used) { 607 if (params.target && !params.target_used) {
495 pr_warning(" Error: -x/-m must follow the probe definitions.\n"); 608 pr_err(" Error: -x/-m must follow the probe definitions.\n");
496 usage_with_options(probe_usage, options); 609 parse_options_usage(probe_usage, options, "m", true);
610 parse_options_usage(NULL, options, "x", true);
611 return -EINVAL;
497 } 612 }
498 613
499 ret = add_perf_probe_events(params.events, params.nevents); 614 ret = perf_add_probe_events(params.events, params.nevents);
500 if (ret < 0) { 615 if (ret < 0) {
501 pr_err_with_code(" Error: Failed to add events.", ret); 616 pr_err_with_code(" Error: Failed to add events.", ret);
502 return ret; 617 return ret;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 142eeb341b29..199fc31e3919 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -31,6 +31,7 @@
31#include "util/auxtrace.h" 31#include "util/auxtrace.h"
32#include "util/parse-branch-options.h" 32#include "util/parse-branch-options.h"
33#include "util/parse-regs-options.h" 33#include "util/parse-regs-options.h"
34#include "util/llvm-utils.h"
34 35
35#include <unistd.h> 36#include <unistd.h>
36#include <sched.h> 37#include <sched.h>
@@ -49,7 +50,7 @@ struct record {
49 int realtime_prio; 50 int realtime_prio;
50 bool no_buildid; 51 bool no_buildid;
51 bool no_buildid_cache; 52 bool no_buildid_cache;
52 long samples; 53 unsigned long long samples;
53}; 54};
54 55
55static int record__write(struct record *rec, void *bf, size_t size) 56static int record__write(struct record *rec, void *bf, size_t size)
@@ -636,8 +637,29 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
636 /* 637 /*
637 * Let the child rip 638 * Let the child rip
638 */ 639 */
639 if (forks) 640 if (forks) {
641 union perf_event *event;
642
643 event = malloc(sizeof(event->comm) + machine->id_hdr_size);
644 if (event == NULL) {
645 err = -ENOMEM;
646 goto out_child;
647 }
648
649 /*
650 * Some H/W events are generated before COMM event
651 * which is emitted during exec(), so perf script
652 * cannot see a correct process name for those events.
653 * Synthesize COMM event to prevent it.
654 */
655 perf_event__synthesize_comm(tool, event,
656 rec->evlist->workload.pid,
657 process_synthesized_event,
658 machine);
659 free(event);
660
640 perf_evlist__start_workload(rec->evlist); 661 perf_evlist__start_workload(rec->evlist);
662 }
641 663
642 if (opts->initial_delay) { 664 if (opts->initial_delay) {
643 usleep(opts->initial_delay * 1000); 665 usleep(opts->initial_delay * 1000);
@@ -646,7 +668,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
646 668
647 auxtrace_snapshot_enabled = 1; 669 auxtrace_snapshot_enabled = 1;
648 for (;;) { 670 for (;;) {
649 int hits = rec->samples; 671 unsigned long long hits = rec->samples;
650 672
651 if (record__mmap_read_all(rec) < 0) { 673 if (record__mmap_read_all(rec) < 0) {
652 auxtrace_snapshot_enabled = 0; 674 auxtrace_snapshot_enabled = 0;
@@ -989,13 +1011,8 @@ static struct record record = {
989 }, 1011 },
990}; 1012};
991 1013
992#define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace) recording: " 1014const char record_callchain_help[] = CALLCHAIN_RECORD_HELP
993 1015 "\n\t\t\t\tDefault: fp";
994#ifdef HAVE_DWARF_UNWIND_SUPPORT
995const char record_callchain_help[] = CALLCHAIN_HELP "fp dwarf lbr";
996#else
997const char record_callchain_help[] = CALLCHAIN_HELP "fp lbr";
998#endif
999 1016
1000/* 1017/*
1001 * XXX Will stay a global variable till we fix builtin-script.c to stop messing 1018 * XXX Will stay a global variable till we fix builtin-script.c to stop messing
@@ -1043,7 +1060,7 @@ struct option __record_options[] = {
1043 NULL, "enables call-graph recording" , 1060 NULL, "enables call-graph recording" ,
1044 &record_callchain_opt), 1061 &record_callchain_opt),
1045 OPT_CALLBACK(0, "call-graph", &record.opts, 1062 OPT_CALLBACK(0, "call-graph", &record.opts,
1046 "mode[,dump_size]", record_callchain_help, 1063 "record_mode[,record_size]", record_callchain_help,
1047 &record_parse_callchain_opt), 1064 &record_parse_callchain_opt),
1048 OPT_INCR('v', "verbose", &verbose, 1065 OPT_INCR('v', "verbose", &verbose,
1049 "be more verbose (show counter open errors, etc)"), 1066 "be more verbose (show counter open errors, etc)"),
@@ -1096,6 +1113,12 @@ struct option __record_options[] = {
1096 "per thread proc mmap processing timeout in ms"), 1113 "per thread proc mmap processing timeout in ms"),
1097 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, 1114 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1098 "Record context switch events"), 1115 "Record context switch events"),
1116#ifdef HAVE_LIBBPF_SUPPORT
1117 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1118 "clang binary to use for compiling BPF scriptlets"),
1119 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1120 "options passed to clang when compiling BPF scriptlets"),
1121#endif
1099 OPT_END() 1122 OPT_END()
1100}; 1123};
1101 1124
@@ -1119,14 +1142,15 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1119 usage_with_options(record_usage, record_options); 1142 usage_with_options(record_usage, record_options);
1120 1143
1121 if (nr_cgroups && !rec->opts.target.system_wide) { 1144 if (nr_cgroups && !rec->opts.target.system_wide) {
1122 ui__error("cgroup monitoring only available in" 1145 usage_with_options_msg(record_usage, record_options,
1123 " system-wide mode\n"); 1146 "cgroup monitoring only available in system-wide mode");
1124 usage_with_options(record_usage, record_options); 1147
1125 } 1148 }
1126 if (rec->opts.record_switch_events && 1149 if (rec->opts.record_switch_events &&
1127 !perf_can_record_switch_events()) { 1150 !perf_can_record_switch_events()) {
1128 ui__error("kernel does not support recording context switch events (--switch-events option)\n"); 1151 ui__error("kernel does not support recording context switch events\n");
1129 usage_with_options(record_usage, record_options); 1152 parse_options_usage(record_usage, record_options, "switch-events", 0);
1153 return -EINVAL;
1130 } 1154 }
1131 1155
1132 if (!rec->itr) { 1156 if (!rec->itr) {
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 62b285e32aa5..2853ad2bd435 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -62,6 +62,7 @@ struct report {
62 float min_percent; 62 float min_percent;
63 u64 nr_entries; 63 u64 nr_entries;
64 u64 queue_size; 64 u64 queue_size;
65 int socket_filter;
65 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 66 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
66}; 67};
67 68
@@ -162,14 +163,21 @@ static int process_sample_event(struct perf_tool *tool,
162 if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap)) 163 if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
163 goto out_put; 164 goto out_put;
164 165
165 if (sort__mode == SORT_MODE__BRANCH) 166 if (sort__mode == SORT_MODE__BRANCH) {
167 /*
168 * A non-synthesized event might not have a branch stack if
169 * branch stacks have been synthesized (using itrace options).
170 */
171 if (!sample->branch_stack)
172 goto out_put;
166 iter.ops = &hist_iter_branch; 173 iter.ops = &hist_iter_branch;
167 else if (rep->mem_mode) 174 } else if (rep->mem_mode) {
168 iter.ops = &hist_iter_mem; 175 iter.ops = &hist_iter_mem;
169 else if (symbol_conf.cumulate_callchain) 176 } else if (symbol_conf.cumulate_callchain) {
170 iter.ops = &hist_iter_cumulative; 177 iter.ops = &hist_iter_cumulative;
171 else 178 } else {
172 iter.ops = &hist_iter_normal; 179 iter.ops = &hist_iter_normal;
180 }
173 181
174 if (al.map != NULL) 182 if (al.map != NULL)
175 al.map->dso->hit = 1; 183 al.map->dso->hit = 1;
@@ -213,6 +221,15 @@ static int report__setup_sample_type(struct report *rep)
213 u64 sample_type = perf_evlist__combined_sample_type(session->evlist); 221 u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
214 bool is_pipe = perf_data_file__is_pipe(session->file); 222 bool is_pipe = perf_data_file__is_pipe(session->file);
215 223
224 if (session->itrace_synth_opts->callchain ||
225 (!is_pipe &&
226 perf_header__has_feat(&session->header, HEADER_AUXTRACE) &&
227 !session->itrace_synth_opts->set))
228 sample_type |= PERF_SAMPLE_CALLCHAIN;
229
230 if (session->itrace_synth_opts->last_branch)
231 sample_type |= PERF_SAMPLE_BRANCH_STACK;
232
216 if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) { 233 if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
217 if (sort__has_parent) { 234 if (sort__has_parent) {
218 ui__error("Selected --sort parent, but no " 235 ui__error("Selected --sort parent, but no "
@@ -286,6 +303,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
286 struct perf_evsel *evsel = hists_to_evsel(hists); 303 struct perf_evsel *evsel = hists_to_evsel(hists);
287 char buf[512]; 304 char buf[512];
288 size_t size = sizeof(buf); 305 size_t size = sizeof(buf);
306 int socked_id = hists->socket_filter;
289 307
290 if (symbol_conf.filter_relative) { 308 if (symbol_conf.filter_relative) {
291 nr_samples = hists->stats.nr_non_filtered_samples; 309 nr_samples = hists->stats.nr_non_filtered_samples;
@@ -326,6 +344,10 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
326 ret += fprintf(fp, "\n# Sort order : %s", sort_order ? : default_mem_sort_order); 344 ret += fprintf(fp, "\n# Sort order : %s", sort_order ? : default_mem_sort_order);
327 } else 345 } else
328 ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events); 346 ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
347
348 if (socked_id > -1)
349 ret += fprintf(fp, "\n# Processor Socket: %d", socked_id);
350
329 return ret + fprintf(fp, "\n#\n"); 351 return ret + fprintf(fp, "\n#\n");
330} 352}
331 353
@@ -365,7 +387,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
365 387
366static void report__warn_kptr_restrict(const struct report *rep) 388static void report__warn_kptr_restrict(const struct report *rep)
367{ 389{
368 struct map *kernel_map = rep->session->machines.host.vmlinux_maps[MAP__FUNCTION]; 390 struct map *kernel_map = machine__kernel_map(&rep->session->machines.host);
369 struct kmap *kernel_kmap = kernel_map ? map__kmap(kernel_map) : NULL; 391 struct kmap *kernel_kmap = kernel_map ? map__kmap(kernel_map) : NULL;
370 392
371 if (kernel_map == NULL || 393 if (kernel_map == NULL ||
@@ -450,6 +472,8 @@ static void report__collapse_hists(struct report *rep)
450 if (pos->idx == 0) 472 if (pos->idx == 0)
451 hists->symbol_filter_str = rep->symbol_filter_str; 473 hists->symbol_filter_str = rep->symbol_filter_str;
452 474
475 hists->socket_filter = rep->socket_filter;
476
453 hists__collapse_resort(hists, &prog); 477 hists__collapse_resort(hists, &prog);
454 478
455 /* Non-group events are considered as leader */ 479 /* Non-group events are considered as leader */
@@ -601,6 +625,12 @@ parse_percent_limit(const struct option *opt, const char *str,
601 return 0; 625 return 0;
602} 626}
603 627
628#define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function"
629
630const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n"
631 CALLCHAIN_REPORT_HELP
632 "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT;
633
604int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) 634int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
605{ 635{
606 struct perf_session *session; 636 struct perf_session *session;
@@ -609,7 +639,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
609 bool has_br_stack = false; 639 bool has_br_stack = false;
610 int branch_mode = -1; 640 int branch_mode = -1;
611 bool branch_call_mode = false; 641 bool branch_call_mode = false;
612 char callchain_default_opt[] = "fractal,0.5,callee"; 642 char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT;
613 const char * const report_usage[] = { 643 const char * const report_usage[] = {
614 "perf report [<options>]", 644 "perf report [<options>]",
615 NULL 645 NULL
@@ -635,6 +665,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
635 }, 665 },
636 .max_stack = PERF_MAX_STACK_DEPTH, 666 .max_stack = PERF_MAX_STACK_DEPTH,
637 .pretty_printing_style = "normal", 667 .pretty_printing_style = "normal",
668 .socket_filter = -1,
638 }; 669 };
639 const struct option options[] = { 670 const struct option options[] = {
640 OPT_STRING('i', "input", &input_name, "file", 671 OPT_STRING('i', "input", &input_name, "file",
@@ -668,15 +699,18 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
668 " Please refer the man page for the complete list."), 699 " Please refer the man page for the complete list."),
669 OPT_STRING('F', "fields", &field_order, "key[,keys...]", 700 OPT_STRING('F', "fields", &field_order, "key[,keys...]",
670 "output field(s): overhead, period, sample plus all of sort keys"), 701 "output field(s): overhead, period, sample plus all of sort keys"),
671 OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization, 702 OPT_BOOLEAN(0, "show-cpu-utilization", &symbol_conf.show_cpu_utilization,
672 "Show sample percentage for different cpu modes"), 703 "Show sample percentage for different cpu modes"),
704 OPT_BOOLEAN_FLAG(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
705 "Show sample percentage for different cpu modes", PARSE_OPT_HIDDEN),
673 OPT_STRING('p', "parent", &parent_pattern, "regex", 706 OPT_STRING('p', "parent", &parent_pattern, "regex",
674 "regex filter to identify parent, see: '--sort parent'"), 707 "regex filter to identify parent, see: '--sort parent'"),
675 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other, 708 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
676 "Only display entries with parent-match"), 709 "Only display entries with parent-match"),
677 OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent[,print_limit],call_order[,branch]", 710 OPT_CALLBACK_DEFAULT('g', "call-graph", &report,
678 "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold, optional print limit, callchain order, key (function or address), add branches. " 711 "print_type,threshold[,print_limit],order,sort_key[,branch]",
679 "Default: fractal,0.5,callee,function", &report_parse_callchain_opt, callchain_default_opt), 712 report_callchain_help, &report_parse_callchain_opt,
713 callchain_default_opt),
680 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, 714 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
681 "Accumulate callchains of children and show total overhead as well"), 715 "Accumulate callchains of children and show total overhead as well"),
682 OPT_INTEGER(0, "max-stack", &report.max_stack, 716 OPT_INTEGER(0, "max-stack", &report.max_stack,
@@ -747,6 +781,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
747 "Show full source file name path for source lines"), 781 "Show full source file name path for source lines"),
748 OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph, 782 OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
749 "Show callgraph from reference event"), 783 "Show callgraph from reference event"),
784 OPT_INTEGER(0, "socket-filter", &report.socket_filter,
785 "only show processor socket that match with this filter"),
750 OPT_END() 786 OPT_END()
751 }; 787 };
752 struct perf_data_file file = { 788 struct perf_data_file file = {
@@ -781,6 +817,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
781 817
782 if (report.inverted_callchain) 818 if (report.inverted_callchain)
783 callchain_param.order = ORDER_CALLER; 819 callchain_param.order = ORDER_CALLER;
820 if (symbol_conf.cumulate_callchain && !callchain_param.order_set)
821 callchain_param.order = ORDER_CALLER;
822
823 if (itrace_synth_opts.callchain &&
824 (int)itrace_synth_opts.callchain_sz > report.max_stack)
825 report.max_stack = itrace_synth_opts.callchain_sz;
784 826
785 if (!input_name || !strlen(input_name)) { 827 if (!input_name || !strlen(input_name)) {
786 if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) 828 if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
@@ -809,6 +851,9 @@ repeat:
809 has_br_stack = perf_header__has_feat(&session->header, 851 has_br_stack = perf_header__has_feat(&session->header,
810 HEADER_BRANCH_STACK); 852 HEADER_BRANCH_STACK);
811 853
854 if (itrace_synth_opts.last_branch)
855 has_br_stack = true;
856
812 /* 857 /*
813 * Branch mode is a tristate: 858 * Branch mode is a tristate:
814 * -1 means default, so decide based on the file having branch data. 859 * -1 means default, so decide based on the file having branch data.
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 33962612a5e9..0ee6d900e100 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1728,8 +1728,8 @@ static void setup_sorting(struct perf_sched *sched, const struct option *options
1728 for (tok = strtok_r(str, ", ", &tmp); 1728 for (tok = strtok_r(str, ", ", &tmp);
1729 tok; tok = strtok_r(NULL, ", ", &tmp)) { 1729 tok; tok = strtok_r(NULL, ", ", &tmp)) {
1730 if (sort_dimension__add(tok, &sched->sort_list) < 0) { 1730 if (sort_dimension__add(tok, &sched->sort_list) < 0) {
1731 error("Unknown --sort key: `%s'", tok); 1731 usage_with_options_msg(usage_msg, options,
1732 usage_with_options(usage_msg, options); 1732 "Unknown --sort key: `%s'", tok);
1733 } 1733 }
1734 } 1734 }
1735 1735
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index eb51325e8ad9..72b5deb4bd79 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -29,9 +29,12 @@ static bool no_callchain;
29static bool latency_format; 29static bool latency_format;
30static bool system_wide; 30static bool system_wide;
31static bool print_flags; 31static bool print_flags;
32static bool nanosecs;
32static const char *cpu_list; 33static const char *cpu_list;
33static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 34static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
34 35
36unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
37
35enum perf_output_field { 38enum perf_output_field {
36 PERF_OUTPUT_COMM = 1U << 0, 39 PERF_OUTPUT_COMM = 1U << 0,
37 PERF_OUTPUT_TID = 1U << 1, 40 PERF_OUTPUT_TID = 1U << 1,
@@ -48,6 +51,8 @@ enum perf_output_field {
48 PERF_OUTPUT_SRCLINE = 1U << 12, 51 PERF_OUTPUT_SRCLINE = 1U << 12,
49 PERF_OUTPUT_PERIOD = 1U << 13, 52 PERF_OUTPUT_PERIOD = 1U << 13,
50 PERF_OUTPUT_IREGS = 1U << 14, 53 PERF_OUTPUT_IREGS = 1U << 14,
54 PERF_OUTPUT_BRSTACK = 1U << 15,
55 PERF_OUTPUT_BRSTACKSYM = 1U << 16,
51}; 56};
52 57
53struct output_option { 58struct output_option {
@@ -69,6 +74,8 @@ struct output_option {
69 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, 74 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
70 {.str = "period", .field = PERF_OUTPUT_PERIOD}, 75 {.str = "period", .field = PERF_OUTPUT_PERIOD},
71 {.str = "iregs", .field = PERF_OUTPUT_IREGS}, 76 {.str = "iregs", .field = PERF_OUTPUT_IREGS},
77 {.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
78 {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
72}; 79};
73 80
74/* default set to maintain compatibility with current format */ 81/* default set to maintain compatibility with current format */
@@ -415,10 +422,84 @@ static void print_sample_start(struct perf_sample *sample,
415 secs = nsecs / NSECS_PER_SEC; 422 secs = nsecs / NSECS_PER_SEC;
416 nsecs -= secs * NSECS_PER_SEC; 423 nsecs -= secs * NSECS_PER_SEC;
417 usecs = nsecs / NSECS_PER_USEC; 424 usecs = nsecs / NSECS_PER_USEC;
418 printf("%5lu.%06lu: ", secs, usecs); 425 if (nanosecs)
426 printf("%5lu.%09llu: ", secs, nsecs);
427 else
428 printf("%5lu.%06lu: ", secs, usecs);
419 } 429 }
420} 430}
421 431
432static inline char
433mispred_str(struct branch_entry *br)
434{
435 if (!(br->flags.mispred || br->flags.predicted))
436 return '-';
437
438 return br->flags.predicted ? 'P' : 'M';
439}
440
441static void print_sample_brstack(union perf_event *event __maybe_unused,
442 struct perf_sample *sample,
443 struct thread *thread __maybe_unused,
444 struct perf_event_attr *attr __maybe_unused)
445{
446 struct branch_stack *br = sample->branch_stack;
447 u64 i;
448
449 if (!(br && br->nr))
450 return;
451
452 for (i = 0; i < br->nr; i++) {
453 printf(" 0x%"PRIx64"/0x%"PRIx64"/%c/%c/%c/%d ",
454 br->entries[i].from,
455 br->entries[i].to,
456 mispred_str( br->entries + i),
457 br->entries[i].flags.in_tx? 'X' : '-',
458 br->entries[i].flags.abort? 'A' : '-',
459 br->entries[i].flags.cycles);
460 }
461}
462
463static void print_sample_brstacksym(union perf_event *event __maybe_unused,
464 struct perf_sample *sample,
465 struct thread *thread __maybe_unused,
466 struct perf_event_attr *attr __maybe_unused)
467{
468 struct branch_stack *br = sample->branch_stack;
469 struct addr_location alf, alt;
470 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
471 u64 i, from, to;
472
473 if (!(br && br->nr))
474 return;
475
476 for (i = 0; i < br->nr; i++) {
477
478 memset(&alf, 0, sizeof(alf));
479 memset(&alt, 0, sizeof(alt));
480 from = br->entries[i].from;
481 to = br->entries[i].to;
482
483 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, from, &alf);
484 if (alf.map)
485 alf.sym = map__find_symbol(alf.map, alf.addr, NULL);
486
487 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, to, &alt);
488 if (alt.map)
489 alt.sym = map__find_symbol(alt.map, alt.addr, NULL);
490
491 symbol__fprintf_symname_offs(alf.sym, &alf, stdout);
492 putchar('/');
493 symbol__fprintf_symname_offs(alt.sym, &alt, stdout);
494 printf("/%c/%c/%c/%d ",
495 mispred_str( br->entries + i),
496 br->entries[i].flags.in_tx? 'X' : '-',
497 br->entries[i].flags.abort? 'A' : '-',
498 br->entries[i].flags.cycles);
499 }
500}
501
502
422static void print_sample_addr(union perf_event *event, 503static void print_sample_addr(union perf_event *event,
423 struct perf_sample *sample, 504 struct perf_sample *sample,
424 struct thread *thread, 505 struct thread *thread,
@@ -471,7 +552,7 @@ static void print_sample_bts(union perf_event *event,
471 } 552 }
472 } 553 }
473 perf_evsel__print_ip(evsel, sample, al, print_opts, 554 perf_evsel__print_ip(evsel, sample, al, print_opts,
474 PERF_MAX_STACK_DEPTH); 555 scripting_max_stack);
475 } 556 }
476 557
477 /* print branch_to information */ 558 /* print branch_to information */
@@ -548,12 +629,17 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
548 629
549 perf_evsel__print_ip(evsel, sample, al, 630 perf_evsel__print_ip(evsel, sample, al,
550 output[attr->type].print_ip_opts, 631 output[attr->type].print_ip_opts,
551 PERF_MAX_STACK_DEPTH); 632 scripting_max_stack);
552 } 633 }
553 634
554 if (PRINT_FIELD(IREGS)) 635 if (PRINT_FIELD(IREGS))
555 print_sample_iregs(event, sample, thread, attr); 636 print_sample_iregs(event, sample, thread, attr);
556 637
638 if (PRINT_FIELD(BRSTACK))
639 print_sample_brstack(event, sample, thread, attr);
640 else if (PRINT_FIELD(BRSTACKSYM))
641 print_sample_brstacksym(event, sample, thread, attr);
642
557 printf("\n"); 643 printf("\n");
558} 644}
559 645
@@ -680,7 +766,10 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
680 766
681 set_print_ip_opts(&evsel->attr); 767 set_print_ip_opts(&evsel->attr);
682 768
683 return perf_evsel__check_attr(evsel, scr->session); 769 if (evsel->attr.sample_type)
770 err = perf_evsel__check_attr(evsel, scr->session);
771
772 return err;
684} 773}
685 774
686static int process_comm_event(struct perf_tool *tool, 775static int process_comm_event(struct perf_tool *tool,
@@ -768,8 +857,8 @@ static int process_exit_event(struct perf_tool *tool,
768 if (!evsel->attr.sample_id_all) { 857 if (!evsel->attr.sample_id_all) {
769 sample->cpu = 0; 858 sample->cpu = 0;
770 sample->time = 0; 859 sample->time = 0;
771 sample->tid = event->comm.tid; 860 sample->tid = event->fork.tid;
772 sample->pid = event->comm.pid; 861 sample->pid = event->fork.pid;
773 } 862 }
774 print_sample_start(sample, thread, evsel); 863 print_sample_start(sample, thread, evsel);
775 perf_event__fprintf(event, stdout); 864 perf_event__fprintf(event, stdout);
@@ -1672,7 +1761,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1672 "comma separated output fields prepend with 'type:'. " 1761 "comma separated output fields prepend with 'type:'. "
1673 "Valid types: hw,sw,trace,raw. " 1762 "Valid types: hw,sw,trace,raw. "
1674 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 1763 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
1675 "addr,symoff,period,iregs,flags", parse_output_fields), 1764 "addr,symoff,period,iregs,brstack,brstacksym,flags", parse_output_fields),
1676 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1765 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1677 "system-wide collection from all CPUs"), 1766 "system-wide collection from all CPUs"),
1678 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 1767 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
@@ -1695,6 +1784,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1695 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events, 1784 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
1696 "Show context switch events (if recorded)"), 1785 "Show context switch events (if recorded)"),
1697 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 1786 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
1787 OPT_BOOLEAN(0, "ns", &nanosecs,
1788 "Use 9 decimal places when displaying time"),
1698 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 1789 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
1699 "Instruction Tracing options", 1790 "Instruction Tracing options",
1700 itrace_parse_synth_opts), 1791 itrace_parse_synth_opts),
@@ -1740,6 +1831,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1740 } 1831 }
1741 } 1832 }
1742 1833
1834 if (itrace_synth_opts.callchain &&
1835 itrace_synth_opts.callchain_sz > scripting_max_stack)
1836 scripting_max_stack = itrace_synth_opts.callchain_sz;
1837
1743 /* make sure PERF_EXEC_PATH is set for scripts */ 1838 /* make sure PERF_EXEC_PATH is set for scripts */
1744 perf_set_argv_exec_path(perf_exec_path()); 1839 perf_set_argv_exec_path(perf_exec_path());
1745 1840
@@ -1752,9 +1847,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1752 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); 1847 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
1753 1848
1754 if (!rec_script_path && !rep_script_path) { 1849 if (!rec_script_path && !rep_script_path) {
1755 fprintf(stderr, " Couldn't find script %s\n\n See perf" 1850 usage_with_options_msg(script_usage, options,
1851 "Couldn't find script `%s'\n\n See perf"
1756 " script -l for available scripts.\n", argv[0]); 1852 " script -l for available scripts.\n", argv[0]);
1757 usage_with_options(script_usage, options);
1758 } 1853 }
1759 1854
1760 if (is_top_script(argv[0])) { 1855 if (is_top_script(argv[0])) {
@@ -1765,10 +1860,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1765 rep_args = has_required_arg(rep_script_path); 1860 rep_args = has_required_arg(rep_script_path);
1766 rec_args = (argc - 1) - rep_args; 1861 rec_args = (argc - 1) - rep_args;
1767 if (rec_args < 0) { 1862 if (rec_args < 0) {
1768 fprintf(stderr, " %s script requires options." 1863 usage_with_options_msg(script_usage, options,
1864 "`%s' script requires options."
1769 "\n\n See perf script -l for available " 1865 "\n\n See perf script -l for available "
1770 "scripts and options.\n", argv[0]); 1866 "scripts and options.\n", argv[0]);
1771 usage_with_options(script_usage, options);
1772 } 1867 }
1773 } 1868 }
1774 1869
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index d46dbb1bc65d..2f438f76cceb 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -100,6 +100,8 @@ static struct target target = {
100 .uid = UINT_MAX, 100 .uid = UINT_MAX,
101}; 101};
102 102
103typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);
104
103static int run_count = 1; 105static int run_count = 1;
104static bool no_inherit = false; 106static bool no_inherit = false;
105static volatile pid_t child_pid = -1; 107static volatile pid_t child_pid = -1;
@@ -119,7 +121,7 @@ static unsigned int unit_width = 4; /* strlen("unit") */
119static bool forever = false; 121static bool forever = false;
120static struct timespec ref_time; 122static struct timespec ref_time;
121static struct cpu_map *aggr_map; 123static struct cpu_map *aggr_map;
122static int (*aggr_get_id)(struct cpu_map *m, int cpu); 124static aggr_get_id_t aggr_get_id;
123 125
124static volatile int done = 0; 126static volatile int done = 0;
125 127
@@ -215,7 +217,7 @@ static void read_counters(bool close_counters)
215 217
216 evlist__for_each(evsel_list, counter) { 218 evlist__for_each(evsel_list, counter) {
217 if (read_counter(counter)) 219 if (read_counter(counter))
218 pr_warning("failed to read counter %s\n", counter->name); 220 pr_debug("failed to read counter %s\n", counter->name);
219 221
220 if (perf_stat_process_counter(&stat_config, counter)) 222 if (perf_stat_process_counter(&stat_config, counter))
221 pr_warning("failed to process counter %s\n", counter->name); 223 pr_warning("failed to process counter %s\n", counter->name);
@@ -434,7 +436,7 @@ static void print_noise_pct(double total, double avg)
434 436
435static void print_noise(struct perf_evsel *evsel, double avg) 437static void print_noise(struct perf_evsel *evsel, double avg)
436{ 438{
437 struct perf_stat *ps; 439 struct perf_stat_evsel *ps;
438 440
439 if (run_count == 1) 441 if (run_count == 1)
440 return; 442 return;
@@ -479,6 +481,7 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
479 csv_sep); 481 csv_sep);
480 break; 482 break;
481 case AGGR_GLOBAL: 483 case AGGR_GLOBAL:
484 case AGGR_UNSET:
482 default: 485 default:
483 break; 486 break;
484 } 487 }
@@ -671,7 +674,7 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
671static void print_counter_aggr(struct perf_evsel *counter, char *prefix) 674static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
672{ 675{
673 FILE *output = stat_config.output; 676 FILE *output = stat_config.output;
674 struct perf_stat *ps = counter->priv; 677 struct perf_stat_evsel *ps = counter->priv;
675 double avg = avg_stats(&ps->res_stats[0]); 678 double avg = avg_stats(&ps->res_stats[0]);
676 int scaled = counter->counts->scaled; 679 int scaled = counter->counts->scaled;
677 double uval; 680 double uval;
@@ -799,6 +802,8 @@ static void print_interval(char *prefix, struct timespec *ts)
799 case AGGR_GLOBAL: 802 case AGGR_GLOBAL:
800 default: 803 default:
801 fprintf(output, "# time counts %*s events\n", unit_width, "unit"); 804 fprintf(output, "# time counts %*s events\n", unit_width, "unit");
805 case AGGR_UNSET:
806 break;
802 } 807 }
803 } 808 }
804 809
@@ -880,6 +885,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
880 evlist__for_each(evsel_list, counter) 885 evlist__for_each(evsel_list, counter)
881 print_counter(counter, prefix); 886 print_counter(counter, prefix);
882 break; 887 break;
888 case AGGR_UNSET:
883 default: 889 default:
884 break; 890 break;
885 } 891 }
@@ -940,30 +946,90 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,
940 return 0; 946 return 0;
941} 947}
942 948
949static int perf_stat__get_socket(struct cpu_map *map, int cpu)
950{
951 return cpu_map__get_socket(map, cpu, NULL);
952}
953
954static int perf_stat__get_core(struct cpu_map *map, int cpu)
955{
956 return cpu_map__get_core(map, cpu, NULL);
957}
958
959static int cpu_map__get_max(struct cpu_map *map)
960{
961 int i, max = -1;
962
963 for (i = 0; i < map->nr; i++) {
964 if (map->map[i] > max)
965 max = map->map[i];
966 }
967
968 return max;
969}
970
971static struct cpu_map *cpus_aggr_map;
972
973static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int idx)
974{
975 int cpu;
976
977 if (idx >= map->nr)
978 return -1;
979
980 cpu = map->map[idx];
981
982 if (cpus_aggr_map->map[cpu] == -1)
983 cpus_aggr_map->map[cpu] = get_id(map, idx);
984
985 return cpus_aggr_map->map[cpu];
986}
987
988static int perf_stat__get_socket_cached(struct cpu_map *map, int idx)
989{
990 return perf_stat__get_aggr(perf_stat__get_socket, map, idx);
991}
992
993static int perf_stat__get_core_cached(struct cpu_map *map, int idx)
994{
995 return perf_stat__get_aggr(perf_stat__get_core, map, idx);
996}
997
943static int perf_stat_init_aggr_mode(void) 998static int perf_stat_init_aggr_mode(void)
944{ 999{
1000 int nr;
1001
945 switch (stat_config.aggr_mode) { 1002 switch (stat_config.aggr_mode) {
946 case AGGR_SOCKET: 1003 case AGGR_SOCKET:
947 if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) { 1004 if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
948 perror("cannot build socket map"); 1005 perror("cannot build socket map");
949 return -1; 1006 return -1;
950 } 1007 }
951 aggr_get_id = cpu_map__get_socket; 1008 aggr_get_id = perf_stat__get_socket_cached;
952 break; 1009 break;
953 case AGGR_CORE: 1010 case AGGR_CORE:
954 if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) { 1011 if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
955 perror("cannot build core map"); 1012 perror("cannot build core map");
956 return -1; 1013 return -1;
957 } 1014 }
958 aggr_get_id = cpu_map__get_core; 1015 aggr_get_id = perf_stat__get_core_cached;
959 break; 1016 break;
960 case AGGR_NONE: 1017 case AGGR_NONE:
961 case AGGR_GLOBAL: 1018 case AGGR_GLOBAL:
962 case AGGR_THREAD: 1019 case AGGR_THREAD:
1020 case AGGR_UNSET:
963 default: 1021 default:
964 break; 1022 break;
965 } 1023 }
966 return 0; 1024
1025 /*
1026 * The evsel_list->cpus is the base we operate on,
1027 * taking the highest cpu number to be the size of
1028 * the aggregation translate cpumap.
1029 */
1030 nr = cpu_map__get_max(evsel_list->cpus);
1031 cpus_aggr_map = cpu_map__empty_new(nr + 1);
1032 return cpus_aggr_map ? 0 : -ENOMEM;
967} 1033}
968 1034
969/* 1035/*
@@ -1179,7 +1245,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1179 OPT_STRING(0, "post", &post_cmd, "command", 1245 OPT_STRING(0, "post", &post_cmd, "command",
1180 "command to run after to the measured command"), 1246 "command to run after to the measured command"),
1181 OPT_UINTEGER('I', "interval-print", &stat_config.interval, 1247 OPT_UINTEGER('I', "interval-print", &stat_config.interval,
1182 "print counts at regular interval in ms (>= 100)"), 1248 "print counts at regular interval in ms (>= 10)"),
1183 OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode, 1249 OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
1184 "aggregate counts per processor socket", AGGR_SOCKET), 1250 "aggregate counts per processor socket", AGGR_SOCKET),
1185 OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode, 1251 OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
@@ -1332,9 +1398,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1332 thread_map__read_comms(evsel_list->threads); 1398 thread_map__read_comms(evsel_list->threads);
1333 1399
1334 if (interval && interval < 100) { 1400 if (interval && interval < 100) {
1335 pr_err("print interval must be >= 100ms\n"); 1401 if (interval < 10) {
1336 parse_options_usage(stat_usage, options, "I", 1); 1402 pr_err("print interval must be >= 10ms\n");
1337 goto out; 1403 parse_options_usage(stat_usage, options, "I", 1);
1404 goto out;
1405 } else
1406 pr_warning("print interval < 100ms. "
1407 "The overhead percentage could be high in some cases. "
1408 "Please proceed with caution.\n");
1338 } 1409 }
1339 1410
1340 if (perf_evlist__alloc_stats(evsel_list, interval)) 1411 if (perf_evlist__alloc_stats(evsel_list, interval))
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 8c465c83aabf..7e2e72e6d9d1 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -655,7 +655,7 @@ static int symbol_filter(struct map *map, struct symbol *sym)
655{ 655{
656 const char *name = sym->name; 656 const char *name = sym->name;
657 657
658 if (!map->dso->kernel) 658 if (!__map__is_kernel(map))
659 return 0; 659 return 0;
660 /* 660 /*
661 * ppc64 uses function descriptors and appends a '.' to the 661 * ppc64 uses function descriptors and appends a '.' to the
@@ -857,9 +857,12 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
857 * TODO: we don't process guest user from host side 857 * TODO: we don't process guest user from host side
858 * except simple counting. 858 * except simple counting.
859 */ 859 */
860 /* Fall thru */
861 default:
862 goto next_event; 860 goto next_event;
861 default:
862 if (event->header.type == PERF_RECORD_SAMPLE)
863 goto next_event;
864 machine = &session->machines.host;
865 break;
863 } 866 }
864 867
865 868
@@ -952,7 +955,7 @@ static int __cmd_top(struct perf_top *top)
952 machines__set_symbol_filter(&top->session->machines, symbol_filter); 955 machines__set_symbol_filter(&top->session->machines, symbol_filter);
953 956
954 if (!objdump_path) { 957 if (!objdump_path) {
955 ret = perf_session_env__lookup_objdump(&top->session->header.env); 958 ret = perf_env__lookup_objdump(&top->session->header.env);
956 if (ret) 959 if (ret)
957 goto out_delete; 960 goto out_delete;
958 } 961 }
@@ -961,8 +964,18 @@ static int __cmd_top(struct perf_top *top)
961 if (ret) 964 if (ret)
962 goto out_delete; 965 goto out_delete;
963 966
967 if (perf_session__register_idle_thread(top->session) == NULL)
968 goto out_delete;
969
964 machine__synthesize_threads(&top->session->machines.host, &opts->target, 970 machine__synthesize_threads(&top->session->machines.host, &opts->target,
965 top->evlist->threads, false, opts->proc_map_timeout); 971 top->evlist->threads, false, opts->proc_map_timeout);
972
973 if (sort__has_socket) {
974 ret = perf_env__read_cpu_topology_map(&perf_env);
975 if (ret < 0)
976 goto out_err_cpu_topo;
977 }
978
966 ret = perf_top__start_counters(top); 979 ret = perf_top__start_counters(top);
967 if (ret) 980 if (ret)
968 goto out_delete; 981 goto out_delete;
@@ -1020,6 +1033,14 @@ out_delete:
1020 top->session = NULL; 1033 top->session = NULL;
1021 1034
1022 return ret; 1035 return ret;
1036
1037out_err_cpu_topo: {
1038 char errbuf[BUFSIZ];
1039 const char *err = strerror_r(-ret, errbuf, sizeof(errbuf));
1040
1041 ui__error("Could not read the CPU topology map: %s\n", err);
1042 goto out_delete;
1043}
1023} 1044}
1024 1045
1025static int 1046static int
@@ -1032,8 +1053,22 @@ callchain_opt(const struct option *opt, const char *arg, int unset)
1032static int 1053static int
1033parse_callchain_opt(const struct option *opt, const char *arg, int unset) 1054parse_callchain_opt(const struct option *opt, const char *arg, int unset)
1034{ 1055{
1035 symbol_conf.use_callchain = true; 1056 struct record_opts *record = (struct record_opts *)opt->value;
1036 return record_parse_callchain_opt(opt, arg, unset); 1057
1058 record->callgraph_set = true;
1059 callchain_param.enabled = !unset;
1060 callchain_param.record_mode = CALLCHAIN_FP;
1061
1062 /*
1063 * --no-call-graph
1064 */
1065 if (unset) {
1066 symbol_conf.use_callchain = false;
1067 callchain_param.record_mode = CALLCHAIN_NONE;
1068 return 0;
1069 }
1070
1071 return parse_callchain_top_opt(arg);
1037} 1072}
1038 1073
1039static int perf_top_config(const char *var, const char *value, void *cb) 1074static int perf_top_config(const char *var, const char *value, void *cb)
@@ -1058,6 +1093,9 @@ parse_percent_limit(const struct option *opt, const char *arg,
1058 return 0; 1093 return 0;
1059} 1094}
1060 1095
1096const char top_callchain_help[] = CALLCHAIN_RECORD_HELP CALLCHAIN_REPORT_HELP
1097 "\n\t\t\t\tDefault: fp,graph,0.5,caller,function";
1098
1061int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) 1099int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1062{ 1100{
1063 char errbuf[BUFSIZ]; 1101 char errbuf[BUFSIZ];
@@ -1133,11 +1171,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1133 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, 1171 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
1134 "Show a column with the number of samples"), 1172 "Show a column with the number of samples"),
1135 OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts, 1173 OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
1136 NULL, "enables call-graph recording", 1174 NULL, "enables call-graph recording and display",
1137 &callchain_opt), 1175 &callchain_opt),
1138 OPT_CALLBACK(0, "call-graph", &top.record_opts, 1176 OPT_CALLBACK(0, "call-graph", &top.record_opts,
1139 "mode[,dump_size]", record_callchain_help, 1177 "record_mode[,record_size],print_type,threshold[,print_limit],order,sort_key[,branch]",
1140 &parse_callchain_opt), 1178 top_callchain_help, &parse_callchain_opt),
1141 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, 1179 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
1142 "Accumulate callchains of children and show total overhead as well"), 1180 "Accumulate callchains of children and show total overhead as well"),
1143 OPT_INTEGER(0, "max-stack", &top.max_stack, 1181 OPT_INTEGER(0, "max-stack", &top.max_stack,
@@ -1267,6 +1305,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1267 perf_hpp__cancel_cumulate(); 1305 perf_hpp__cancel_cumulate();
1268 } 1306 }
1269 1307
1308 if (symbol_conf.cumulate_callchain && !callchain_param.order_set)
1309 callchain_param.order = ORDER_CALLER;
1310
1270 symbol_conf.priv_size = sizeof(struct annotation); 1311 symbol_conf.priv_size = sizeof(struct annotation);
1271 1312
1272 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 1313 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 4e3abba03062..c783d8fd3a80 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <traceevent/event-parse.h> 19#include <traceevent/event-parse.h>
20#include <api/fs/tracing_path.h>
20#include "builtin.h" 21#include "builtin.h"
21#include "util/color.h" 22#include "util/color.h"
22#include "util/debug.h" 23#include "util/debug.h"
@@ -37,6 +38,7 @@
37#include <stdlib.h> 38#include <stdlib.h>
38#include <sys/mman.h> 39#include <sys/mman.h>
39#include <linux/futex.h> 40#include <linux/futex.h>
41#include <linux/err.h>
40 42
41/* For older distros: */ 43/* For older distros: */
42#ifndef MAP_STACK 44#ifndef MAP_STACK
@@ -244,13 +246,14 @@ static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction, void
244 struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction); 246 struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction);
245 247
246 /* older kernel (e.g., RHEL6) use syscalls:{enter,exit} */ 248 /* older kernel (e.g., RHEL6) use syscalls:{enter,exit} */
247 if (evsel == NULL) 249 if (IS_ERR(evsel))
248 evsel = perf_evsel__newtp("syscalls", direction); 250 evsel = perf_evsel__newtp("syscalls", direction);
249 251
250 if (evsel) { 252 if (IS_ERR(evsel))
251 if (perf_evsel__init_syscall_tp(evsel, handler)) 253 return NULL;
252 goto out_delete; 254
253 } 255 if (perf_evsel__init_syscall_tp(evsel, handler))
256 goto out_delete;
254 257
255 return evsel; 258 return evsel;
256 259
@@ -582,6 +585,12 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct sysc
582 585
583#define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op 586#define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op
584 587
588static const char *bpf_cmd[] = {
589 "MAP_CREATE", "MAP_LOOKUP_ELEM", "MAP_UPDATE_ELEM", "MAP_DELETE_ELEM",
590 "MAP_GET_NEXT_KEY", "PROG_LOAD",
591};
592static DEFINE_STRARRAY(bpf_cmd);
593
585static const char *epoll_ctl_ops[] = { "ADD", "DEL", "MOD", }; 594static const char *epoll_ctl_ops[] = { "ADD", "DEL", "MOD", };
586static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1); 595static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1);
587 596
@@ -1008,6 +1017,7 @@ static struct syscall_fmt {
1008 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ 1017 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */
1009 [1] = SCA_ACCMODE, /* mode */ }, }, 1018 [1] = SCA_ACCMODE, /* mode */ }, },
1010 { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, 1019 { .name = "arch_prctl", .errmsg = true, .alias = "prctl", },
1020 { .name = "bpf", .errmsg = true, STRARRAY(0, cmd, bpf_cmd), },
1011 { .name = "brk", .hexret = true, 1021 { .name = "brk", .hexret = true,
1012 .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, 1022 .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, },
1013 { .name = "chdir", .errmsg = true, 1023 { .name = "chdir", .errmsg = true,
@@ -1704,12 +1714,12 @@ static int trace__read_syscall_info(struct trace *trace, int id)
1704 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name); 1714 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
1705 sc->tp_format = trace_event__tp_format("syscalls", tp_name); 1715 sc->tp_format = trace_event__tp_format("syscalls", tp_name);
1706 1716
1707 if (sc->tp_format == NULL && sc->fmt && sc->fmt->alias) { 1717 if (IS_ERR(sc->tp_format) && sc->fmt && sc->fmt->alias) {
1708 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->fmt->alias); 1718 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->fmt->alias);
1709 sc->tp_format = trace_event__tp_format("syscalls", tp_name); 1719 sc->tp_format = trace_event__tp_format("syscalls", tp_name);
1710 } 1720 }
1711 1721
1712 if (sc->tp_format == NULL) 1722 if (IS_ERR(sc->tp_format))
1713 return -1; 1723 return -1;
1714 1724
1715 sc->args = sc->tp_format->format.fields; 1725 sc->args = sc->tp_format->format.fields;
@@ -2389,7 +2399,8 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp);
2389static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist) 2399static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist)
2390{ 2400{
2391 struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname"); 2401 struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname");
2392 if (evsel == NULL) 2402
2403 if (IS_ERR(evsel))
2393 return false; 2404 return false;
2394 2405
2395 if (perf_evsel__field(evsel, "pathname") == NULL) { 2406 if (perf_evsel__field(evsel, "pathname") == NULL) {
@@ -2686,11 +2697,11 @@ out_delete_evlist:
2686 char errbuf[BUFSIZ]; 2697 char errbuf[BUFSIZ];
2687 2698
2688out_error_sched_stat_runtime: 2699out_error_sched_stat_runtime:
2689 debugfs__strerror_open_tp(errno, errbuf, sizeof(errbuf), "sched", "sched_stat_runtime"); 2700 tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "sched", "sched_stat_runtime");
2690 goto out_error; 2701 goto out_error;
2691 2702
2692out_error_raw_syscalls: 2703out_error_raw_syscalls:
2693 debugfs__strerror_open_tp(errno, errbuf, sizeof(errbuf), "raw_syscalls", "sys_(enter|exit)"); 2704 tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "raw_syscalls", "sys_(enter|exit)");
2694 goto out_error; 2705 goto out_error;
2695 2706
2696out_error_mmap: 2707out_error_mmap:
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 827557fc7511..de89ec574361 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -106,9 +106,14 @@ ifdef LIBBABELTRACE
106 FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf 106 FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
107endif 107endif
108 108
109FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/arch/$(ARCH)/include/uapi -I$(srctree)/include/uapi
109# include ARCH specific config 110# include ARCH specific config
110-include $(src-perf)/arch/$(ARCH)/Makefile 111-include $(src-perf)/arch/$(ARCH)/Makefile
111 112
113ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
114 CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
115endif
116
112include $(src-perf)/config/utilities.mak 117include $(src-perf)/config/utilities.mak
113 118
114ifeq ($(call get-executable,$(FLEX)),) 119ifeq ($(call get-executable,$(FLEX)),)
@@ -233,6 +238,7 @@ ifdef NO_LIBELF
233 NO_DEMANGLE := 1 238 NO_DEMANGLE := 1
234 NO_LIBUNWIND := 1 239 NO_LIBUNWIND := 1
235 NO_LIBDW_DWARF_UNWIND := 1 240 NO_LIBDW_DWARF_UNWIND := 1
241 NO_LIBBPF := 1
236else 242else
237 ifeq ($(feature-libelf), 0) 243 ifeq ($(feature-libelf), 0)
238 ifeq ($(feature-glibc), 1) 244 ifeq ($(feature-glibc), 1)
@@ -242,13 +248,14 @@ else
242 LIBC_SUPPORT := 1 248 LIBC_SUPPORT := 1
243 endif 249 endif
244 ifeq ($(LIBC_SUPPORT),1) 250 ifeq ($(LIBC_SUPPORT),1)
245 msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev); 251 msg := $(warning No libelf found, disables 'probe' tool and BPF support in 'perf record', please install elfutils-libelf-devel/libelf-dev);
246 252
247 NO_LIBELF := 1 253 NO_LIBELF := 1
248 NO_DWARF := 1 254 NO_DWARF := 1
249 NO_DEMANGLE := 1 255 NO_DEMANGLE := 1
250 NO_LIBUNWIND := 1 256 NO_LIBUNWIND := 1
251 NO_LIBDW_DWARF_UNWIND := 1 257 NO_LIBDW_DWARF_UNWIND := 1
258 NO_LIBBPF := 1
252 else 259 else
253 ifneq ($(filter s% -static%,$(LDFLAGS),),) 260 ifneq ($(filter s% -static%,$(LDFLAGS),),)
254 msg := $(error No static glibc found, please install glibc-static); 261 msg := $(error No static glibc found, please install glibc-static);
@@ -305,6 +312,13 @@ ifndef NO_LIBELF
305 $(call detected,CONFIG_DWARF) 312 $(call detected,CONFIG_DWARF)
306 endif # PERF_HAVE_DWARF_REGS 313 endif # PERF_HAVE_DWARF_REGS
307 endif # NO_DWARF 314 endif # NO_DWARF
315
316 ifndef NO_LIBBPF
317 ifeq ($(feature-bpf), 1)
318 CFLAGS += -DHAVE_LIBBPF_SUPPORT
319 $(call detected,CONFIG_LIBBPF)
320 endif
321 endif # NO_LIBBPF
308endif # NO_LIBELF 322endif # NO_LIBELF
309 323
310ifeq ($(ARCH),powerpc) 324ifeq ($(ARCH),powerpc)
@@ -320,6 +334,13 @@ ifndef NO_LIBUNWIND
320 endif 334 endif
321endif 335endif
322 336
337ifndef NO_LIBBPF
338 ifneq ($(feature-bpf), 1)
339 msg := $(warning BPF API too old. Please install recent kernel headers. BPF support in 'perf record' is disabled.)
340 NO_LIBBPF := 1
341 endif
342endif
343
323dwarf-post-unwind := 1 344dwarf-post-unwind := 1
324dwarf-post-unwind-text := BUG 345dwarf-post-unwind-text := BUG
325 346
@@ -573,9 +594,14 @@ ifndef NO_LIBNUMA
573 msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev); 594 msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev);
574 NO_LIBNUMA := 1 595 NO_LIBNUMA := 1
575 else 596 else
576 CFLAGS += -DHAVE_LIBNUMA_SUPPORT 597 ifeq ($(feature-numa_num_possible_cpus), 0)
577 EXTLIBS += -lnuma 598 msg := $(warning Old numa library found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev >= 2.0.8);
578 $(call detected,CONFIG_NUMA) 599 NO_LIBNUMA := 1
600 else
601 CFLAGS += -DHAVE_LIBNUMA_SUPPORT
602 EXTLIBS += -lnuma
603 $(call detected,CONFIG_NUMA)
604 endif
579 endif 605 endif
580endif 606endif
581 607
@@ -621,8 +647,13 @@ ifdef LIBBABELTRACE
621endif 647endif
622 648
623ifndef NO_AUXTRACE 649ifndef NO_AUXTRACE
624 $(call detected,CONFIG_AUXTRACE) 650 ifeq ($(feature-get_cpuid), 0)
625 CFLAGS += -DHAVE_AUXTRACE_SUPPORT 651 msg := $(warning Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc);
652 NO_AUXTRACE := 1
653 else
654 $(call detected,CONFIG_AUXTRACE)
655 CFLAGS += -DHAVE_AUXTRACE_SUPPORT
656 endif
626endif 657endif
627 658
628# Among the variables below, these: 659# Among the variables below, these:
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 07dbff5c0e60..3d4c7c09adea 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -8,14 +8,16 @@
8 */ 8 */
9#include "builtin.h" 9#include "builtin.h"
10 10
11#include "util/env.h"
11#include "util/exec_cmd.h" 12#include "util/exec_cmd.h"
12#include "util/cache.h" 13#include "util/cache.h"
13#include "util/quote.h" 14#include "util/quote.h"
14#include "util/run-command.h" 15#include "util/run-command.h"
15#include "util/parse-events.h" 16#include "util/parse-events.h"
16#include "util/parse-options.h" 17#include "util/parse-options.h"
18#include "util/bpf-loader.h"
17#include "util/debug.h" 19#include "util/debug.h"
18#include <api/fs/debugfs.h> 20#include <api/fs/tracing_path.h>
19#include <pthread.h> 21#include <pthread.h>
20 22
21const char perf_usage_string[] = 23const char perf_usage_string[] =
@@ -161,6 +163,20 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
161 break; 163 break;
162 164
163 /* 165 /*
166 * Shortcut for '-h' and '-v' options to invoke help
167 * and version command.
168 */
169 if (!strcmp(cmd, "-h")) {
170 (*argv)[0] = "--help";
171 break;
172 }
173
174 if (!strcmp(cmd, "-v")) {
175 (*argv)[0] = "--version";
176 break;
177 }
178
179 /*
164 * Check remaining flags. 180 * Check remaining flags.
165 */ 181 */
166 if (!prefixcmp(cmd, CMD_EXEC_PATH)) { 182 if (!prefixcmp(cmd, CMD_EXEC_PATH)) {
@@ -214,7 +230,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
214 fprintf(stderr, "No directory given for --debugfs-dir.\n"); 230 fprintf(stderr, "No directory given for --debugfs-dir.\n");
215 usage(perf_usage_string); 231 usage(perf_usage_string);
216 } 232 }
217 perf_debugfs_set_path((*argv)[1]); 233 tracing_path_set((*argv)[1]);
218 if (envchanged) 234 if (envchanged)
219 *envchanged = 1; 235 *envchanged = 1;
220 (*argv)++; 236 (*argv)++;
@@ -230,7 +246,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
230 (*argv)++; 246 (*argv)++;
231 (*argc)--; 247 (*argc)--;
232 } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { 248 } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) {
233 perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR)); 249 tracing_path_set(cmd + strlen(CMD_DEBUGFS_DIR));
234 fprintf(stderr, "dir: %s\n", tracing_path); 250 fprintf(stderr, "dir: %s\n", tracing_path);
235 if (envchanged) 251 if (envchanged)
236 *envchanged = 1; 252 *envchanged = 1;
@@ -369,6 +385,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
369 385
370 status = p->fn(argc, argv, prefix); 386 status = p->fn(argc, argv, prefix);
371 exit_browser(status); 387 exit_browser(status);
388 perf_env__exit(&perf_env);
389 bpf__clear();
372 390
373 if (status) 391 if (status)
374 return status & 0xff; 392 return status & 0xff;
@@ -517,8 +535,10 @@ int main(int argc, const char **argv)
517 cmd = perf_extract_argv0_path(argv[0]); 535 cmd = perf_extract_argv0_path(argv[0]);
518 if (!cmd) 536 if (!cmd)
519 cmd = "perf-help"; 537 cmd = "perf-help";
520 /* get debugfs mount point from /proc/mounts */ 538
521 perf_debugfs_mount(NULL); 539 /* get debugfs/tracefs mount point from /proc/mounts */
540 tracing_path_mount();
541
522 /* 542 /*
523 * "perf-xxxx" is the same as "perf xxxx", but we obviously: 543 * "perf-xxxx" is the same as "perf xxxx", but we obviously:
524 * 544 *
diff --git a/tools/perf/python/twatch.py b/tools/perf/python/twatch.py
index b9d508336ae6..c235c22b107a 100755
--- a/tools/perf/python/twatch.py
+++ b/tools/perf/python/twatch.py
@@ -15,14 +15,14 @@
15 15
16import perf 16import perf
17 17
18def main(): 18def main(context_switch = 0, thread = -1):
19 cpus = perf.cpu_map() 19 cpus = perf.cpu_map()
20 threads = perf.thread_map() 20 threads = perf.thread_map(thread)
21 evsel = perf.evsel(type = perf.TYPE_SOFTWARE, 21 evsel = perf.evsel(type = perf.TYPE_SOFTWARE,
22 config = perf.COUNT_SW_DUMMY, 22 config = perf.COUNT_SW_DUMMY,
23 task = 1, comm = 1, mmap = 0, freq = 0, 23 task = 1, comm = 1, mmap = 0, freq = 0,
24 wakeup_events = 1, watermark = 1, 24 wakeup_events = 1, watermark = 1,
25 sample_id_all = 1, 25 sample_id_all = 1, context_switch = context_switch,
26 sample_type = perf.SAMPLE_PERIOD | perf.SAMPLE_TID | perf.SAMPLE_CPU) 26 sample_type = perf.SAMPLE_PERIOD | perf.SAMPLE_TID | perf.SAMPLE_CPU)
27 27
28 """What we want are just the PERF_RECORD_ lifetime events for threads, 28 """What we want are just the PERF_RECORD_ lifetime events for threads,
@@ -48,4 +48,21 @@ def main():
48 print event 48 print event
49 49
50if __name__ == '__main__': 50if __name__ == '__main__':
51 """
52 To test the PERF_RECORD_SWITCH record, pick a pid and replace
53 in the following line.
54
55 Example output:
56
57cpu: 3, pid: 31463, tid: 31593 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31593, switch_out: 1 }
58cpu: 1, pid: 31463, tid: 31489 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31489, switch_out: 1 }
59cpu: 2, pid: 31463, tid: 31496 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31496, switch_out: 1 }
60cpu: 3, pid: 31463, tid: 31491 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31491, switch_out: 0 }
61
62 It is possible as well to use event.misc & perf.PERF_RECORD_MISC_SWITCH_OUT
63 to figure out if this is a context switch in or out of the monitored threads.
64
65 If bored, please add command line option parsing support for these options :-)
66 """
67 # main(context_switch = 1, thread = 31463)
51 main() 68 main()
diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py
index 84a32037a80f..1b02cdc0cab6 100644
--- a/tools/perf/scripts/python/export-to-postgresql.py
+++ b/tools/perf/scripts/python/export-to-postgresql.py
@@ -61,6 +61,142 @@ import datetime
61# 61#
62# An example of using the database is provided by the script 62# An example of using the database is provided by the script
63# call-graph-from-postgresql.py. Refer to that script for details. 63# call-graph-from-postgresql.py. Refer to that script for details.
64#
65# Tables:
66#
67# The tables largely correspond to perf tools' data structures. They are largely self-explanatory.
68#
69# samples
70#
71# 'samples' is the main table. It represents what instruction was executing at a point in time
72# when something (a selected event) happened. The memory address is the instruction pointer or 'ip'.
73#
74# calls
75#
76# 'calls' represents function calls and is related to 'samples' by 'call_id' and 'return_id'.
77# 'calls' is only created when the 'calls' option to this script is specified.
78#
79# call_paths
80#
81# 'call_paths' represents all the call stacks. Each 'call' has an associated record in 'call_paths'.
82# 'calls_paths' is only created when the 'calls' option to this script is specified.
83#
84# branch_types
85#
86# 'branch_types' provides descriptions for each type of branch.
87#
88# comm_threads
89#
90# 'comm_threads' shows how 'comms' relates to 'threads'.
91#
92# comms
93#
94# 'comms' contains a record for each 'comm' - the name given to the executable that is running.
95#
96# dsos
97#
98# 'dsos' contains a record for each executable file or library.
99#
100# machines
101#
102# 'machines' can be used to distinguish virtual machines if virtualization is supported.
103#
104# selected_events
105#
106# 'selected_events' contains a record for each kind of event that has been sampled.
107#
108# symbols
109#
110# 'symbols' contains a record for each symbol. Only symbols that have samples are present.
111#
112# threads
113#
114# 'threads' contains a record for each thread.
115#
116# Views:
117#
118# Most of the tables have views for more friendly display. The views are:
119#
120# calls_view
121# call_paths_view
122# comm_threads_view
123# dsos_view
124# machines_view
125# samples_view
126# symbols_view
127# threads_view
128#
129# More examples of browsing the database with psql:
130# Note that some of the examples are not the most optimal SQL query.
131# Note that call information is only available if the script's 'calls' option has been used.
132#
133# Top 10 function calls (not aggregated by symbol):
134#
135# SELECT * FROM calls_view ORDER BY elapsed_time DESC LIMIT 10;
136#
137# Top 10 function calls (aggregated by symbol):
138#
139# SELECT symbol_id,(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,
140# SUM(elapsed_time) AS tot_elapsed_time,SUM(branch_count) AS tot_branch_count
141# FROM calls_view GROUP BY symbol_id ORDER BY tot_elapsed_time DESC LIMIT 10;
142#
143# Note that the branch count gives a rough estimation of cpu usage, so functions
144# that took a long time but have a relatively low branch count must have spent time
145# waiting.
146#
147# Find symbols by pattern matching on part of the name (e.g. names containing 'alloc'):
148#
149# SELECT * FROM symbols_view WHERE name LIKE '%alloc%';
150#
151# Top 10 function calls for a specific symbol (e.g. whose symbol_id is 187):
152#
153# SELECT * FROM calls_view WHERE symbol_id = 187 ORDER BY elapsed_time DESC LIMIT 10;
154#
155# Show function calls made by function in the same context (i.e. same call path) (e.g. one with call_path_id 254):
156#
157# SELECT * FROM calls_view WHERE parent_call_path_id = 254;
158#
159# Show branches made during a function call (e.g. where call_id is 29357 and return_id is 29370 and tid is 29670)
160#
161# SELECT * FROM samples_view WHERE id >= 29357 AND id <= 29370 AND tid = 29670 AND event LIKE 'branches%';
162#
163# Show transactions:
164#
165# SELECT * FROM samples_view WHERE event = 'transactions';
166#
167# Note transaction start has 'in_tx' true whereas, transaction end has 'in_tx' false.
168# Transaction aborts have branch_type_name 'transaction abort'
169#
170# Show transaction aborts:
171#
172# SELECT * FROM samples_view WHERE event = 'transactions' AND branch_type_name = 'transaction abort';
173#
174# To print a call stack requires walking the call_paths table. For example this python script:
175# #!/usr/bin/python2
176#
177# import sys
178# from PySide.QtSql import *
179#
180# if __name__ == '__main__':
181# if (len(sys.argv) < 3):
182# print >> sys.stderr, "Usage is: printcallstack.py <database name> <call_path_id>"
183# raise Exception("Too few arguments")
184# dbname = sys.argv[1]
185# call_path_id = sys.argv[2]
186# db = QSqlDatabase.addDatabase('QPSQL')
187# db.setDatabaseName(dbname)
188# if not db.open():
189# raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text())
190# query = QSqlQuery(db)
191# print " id ip symbol_id symbol dso_id dso_short_name"
192# while call_path_id != 0 and call_path_id != 1:
193# ret = query.exec_('SELECT * FROM call_paths_view WHERE id = ' + str(call_path_id))
194# if not ret:
195# raise Exception("Query failed: " + query.lastError().text())
196# if not query.next():
197# raise Exception("Query failed")
198# print "{0:>6} {1:>10} {2:>9} {3:<30} {4:>6} {5:<30}".format(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4), query.value(5))
199# call_path_id = query.value(6)
64 200
65from PySide.QtSql import * 201from PySide.QtSql import *
66 202
@@ -244,6 +380,91 @@ if perf_db_export_calls:
244 'parent_call_path_id bigint,' 380 'parent_call_path_id bigint,'
245 'flags integer)') 381 'flags integer)')
246 382
383do_query(query, 'CREATE VIEW machines_view AS '
384 'SELECT '
385 'id,'
386 'pid,'
387 'root_dir,'
388 'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest'
389 ' FROM machines')
390
391do_query(query, 'CREATE VIEW dsos_view AS '
392 'SELECT '
393 'id,'
394 'machine_id,'
395 '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
396 'short_name,'
397 'long_name,'
398 'build_id'
399 ' FROM dsos')
400
401do_query(query, 'CREATE VIEW symbols_view AS '
402 'SELECT '
403 'id,'
404 'name,'
405 '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,'
406 'dso_id,'
407 'sym_start,'
408 'sym_end,'
409 'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding'
410 ' FROM symbols')
411
412do_query(query, 'CREATE VIEW threads_view AS '
413 'SELECT '
414 'id,'
415 'machine_id,'
416 '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
417 'process_id,'
418 'pid,'
419 'tid'
420 ' FROM threads')
421
422do_query(query, 'CREATE VIEW comm_threads_view AS '
423 'SELECT '
424 'comm_id,'
425 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
426 'thread_id,'
427 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
428 '(SELECT tid FROM threads WHERE id = thread_id) AS tid'
429 ' FROM comm_threads')
430
431if perf_db_export_calls:
432 do_query(query, 'CREATE VIEW call_paths_view AS '
433 'SELECT '
434 'c.id,'
435 'to_hex(c.ip) AS ip,'
436 'c.symbol_id,'
437 '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,'
438 '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,'
439 '(SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,'
440 'c.parent_id,'
441 'to_hex(p.ip) AS parent_ip,'
442 'p.symbol_id AS parent_symbol_id,'
443 '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,'
444 '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,'
445 '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name'
446 ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id')
447 do_query(query, 'CREATE VIEW calls_view AS '
448 'SELECT '
449 'calls.id,'
450 'thread_id,'
451 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
452 '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
453 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
454 'call_path_id,'
455 'to_hex(ip) AS ip,'
456 'symbol_id,'
457 '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
458 'call_time,'
459 'return_time,'
460 'return_time - call_time AS elapsed_time,'
461 'branch_count,'
462 'call_id,'
463 'return_id,'
464 'CASE WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' ELSE \'\' END AS flags,'
465 'parent_call_path_id'
466 ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id')
467
247do_query(query, 'CREATE VIEW samples_view AS ' 468do_query(query, 'CREATE VIEW samples_view AS '
248 'SELECT ' 469 'SELECT '
249 'id,' 470 'id,'
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index c1518bdd0f1b..50de2253cff6 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -8,7 +8,6 @@ perf-y += openat-syscall-all-cpus.o
8perf-y += openat-syscall-tp-fields.o 8perf-y += openat-syscall-tp-fields.o
9perf-y += mmap-basic.o 9perf-y += mmap-basic.o
10perf-y += perf-record.o 10perf-y += perf-record.o
11perf-y += rdpmc.o
12perf-y += evsel-roundtrip-name.o 11perf-y += evsel-roundtrip-name.o
13perf-y += evsel-tp-sched.o 12perf-y += evsel-tp-sched.o
14perf-y += fdarray.o 13perf-y += fdarray.o
@@ -33,8 +32,7 @@ perf-y += parse-no-sample-id-all.o
33perf-y += kmod-path.o 32perf-y += kmod-path.o
34perf-y += thread-map.o 33perf-y += thread-map.o
35perf-y += llvm.o 34perf-y += llvm.o
36 35perf-y += topology.o
37perf-$(CONFIG_X86) += perf-time-to-tsc.o
38 36
39ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64)) 37ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64))
40perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o 38perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
diff --git a/tools/perf/tests/bpf-script-example.c b/tools/perf/tests/bpf-script-example.c
new file mode 100644
index 000000000000..410a70b93b93
--- /dev/null
+++ b/tools/perf/tests/bpf-script-example.c
@@ -0,0 +1,44 @@
1#ifndef LINUX_VERSION_CODE
2# error Need LINUX_VERSION_CODE
3# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
4#endif
5#define BPF_ANY 0
6#define BPF_MAP_TYPE_ARRAY 2
7#define BPF_FUNC_map_lookup_elem 1
8#define BPF_FUNC_map_update_elem 2
9
10static void *(*bpf_map_lookup_elem)(void *map, void *key) =
11 (void *) BPF_FUNC_map_lookup_elem;
12static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) =
13 (void *) BPF_FUNC_map_update_elem;
14
15struct bpf_map_def {
16 unsigned int type;
17 unsigned int key_size;
18 unsigned int value_size;
19 unsigned int max_entries;
20};
21
22#define SEC(NAME) __attribute__((section(NAME), used))
23struct bpf_map_def SEC("maps") flip_table = {
24 .type = BPF_MAP_TYPE_ARRAY,
25 .key_size = sizeof(int),
26 .value_size = sizeof(int),
27 .max_entries = 1,
28};
29
30SEC("func=sys_epoll_pwait")
31int bpf_func__sys_epoll_pwait(void *ctx)
32{
33 int ind =0;
34 int *flag = bpf_map_lookup_elem(&flip_table, &ind);
35 int new_flag;
36 if (!flag)
37 return 0;
38 /* flip flag and store back */
39 new_flag = !*flag;
40 bpf_map_update_elem(&flip_table, &ind, &new_flag, BPF_ANY);
41 return new_flag;
42}
43char _license[] SEC("license") = "GPL";
44int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 136cd934be66..66f72d3d6677 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -14,10 +14,13 @@
14#include "parse-options.h" 14#include "parse-options.h"
15#include "symbol.h" 15#include "symbol.h"
16 16
17static struct test { 17struct test __weak arch_tests[] = {
18 const char *desc; 18 {
19 int (*func)(void); 19 .func = NULL,
20} tests[] = { 20 },
21};
22
23static struct test generic_tests[] = {
21 { 24 {
22 .desc = "vmlinux symtab matches kallsyms", 25 .desc = "vmlinux symtab matches kallsyms",
23 .func = test__vmlinux_matches_kallsyms, 26 .func = test__vmlinux_matches_kallsyms,
@@ -38,12 +41,6 @@ static struct test {
38 .desc = "parse events tests", 41 .desc = "parse events tests",
39 .func = test__parse_events, 42 .func = test__parse_events,
40 }, 43 },
41#if defined(__x86_64__) || defined(__i386__)
42 {
43 .desc = "x86 rdpmc test",
44 .func = test__rdpmc,
45 },
46#endif
47 { 44 {
48 .desc = "Validate PERF_RECORD_* events & perf_sample fields", 45 .desc = "Validate PERF_RECORD_* events & perf_sample fields",
49 .func = test__PERF_RECORD, 46 .func = test__PERF_RECORD,
@@ -104,12 +101,6 @@ static struct test {
104 .desc = "Test software clock events have valid period values", 101 .desc = "Test software clock events have valid period values",
105 .func = test__sw_clock_freq, 102 .func = test__sw_clock_freq,
106 }, 103 },
107#if defined(__x86_64__) || defined(__i386__)
108 {
109 .desc = "Test converting perf time to TSC",
110 .func = test__perf_time_to_tsc,
111 },
112#endif
113 { 104 {
114 .desc = "Test object code reading", 105 .desc = "Test object code reading",
115 .func = test__code_reading, 106 .func = test__code_reading,
@@ -126,14 +117,6 @@ static struct test {
126 .desc = "Test parsing with no sample_id_all bit set", 117 .desc = "Test parsing with no sample_id_all bit set",
127 .func = test__parse_no_sample_id_all, 118 .func = test__parse_no_sample_id_all,
128 }, 119 },
129#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
130#ifdef HAVE_DWARF_UNWIND_SUPPORT
131 {
132 .desc = "Test dwarf unwind",
133 .func = test__dwarf_unwind,
134 },
135#endif
136#endif
137 { 120 {
138 .desc = "Test filtering hist entries", 121 .desc = "Test filtering hist entries",
139 .func = test__hists_filter, 122 .func = test__hists_filter,
@@ -179,11 +162,20 @@ static struct test {
179 .func = test__llvm, 162 .func = test__llvm,
180 }, 163 },
181 { 164 {
165 .desc = "Test topology in session",
166 .func = test_session_topology,
167 },
168 {
182 .func = NULL, 169 .func = NULL,
183 }, 170 },
184}; 171};
185 172
186static bool perf_test__matches(int curr, int argc, const char *argv[]) 173static struct test *tests[] = {
174 generic_tests,
175 arch_tests,
176};
177
178static bool perf_test__matches(struct test *test, int curr, int argc, const char *argv[])
187{ 179{
188 int i; 180 int i;
189 181
@@ -200,7 +192,7 @@ static bool perf_test__matches(int curr, int argc, const char *argv[])
200 continue; 192 continue;
201 } 193 }
202 194
203 if (strstr(tests[curr].desc, argv[i])) 195 if (strstr(test->desc, argv[i]))
204 return true; 196 return true;
205 } 197 }
206 198
@@ -237,27 +229,31 @@ static int run_test(struct test *test)
237 return err; 229 return err;
238} 230}
239 231
232#define for_each_test(j, t) \
233 for (j = 0; j < ARRAY_SIZE(tests); j++) \
234 for (t = &tests[j][0]; t->func; t++)
235
240static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) 236static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
241{ 237{
238 struct test *t;
239 unsigned int j;
242 int i = 0; 240 int i = 0;
243 int width = 0; 241 int width = 0;
244 242
245 while (tests[i].func) { 243 for_each_test(j, t) {
246 int len = strlen(tests[i].desc); 244 int len = strlen(t->desc);
247 245
248 if (width < len) 246 if (width < len)
249 width = len; 247 width = len;
250 ++i;
251 } 248 }
252 249
253 i = 0; 250 for_each_test(j, t) {
254 while (tests[i].func) {
255 int curr = i++, err; 251 int curr = i++, err;
256 252
257 if (!perf_test__matches(curr, argc, argv)) 253 if (!perf_test__matches(t, curr, argc, argv))
258 continue; 254 continue;
259 255
260 pr_info("%2d: %-*s:", i, width, tests[curr].desc); 256 pr_info("%2d: %-*s:", i, width, t->desc);
261 257
262 if (intlist__find(skiplist, i)) { 258 if (intlist__find(skiplist, i)) {
263 color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); 259 color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
@@ -265,8 +261,8 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
265 } 261 }
266 262
267 pr_debug("\n--- start ---\n"); 263 pr_debug("\n--- start ---\n");
268 err = run_test(&tests[curr]); 264 err = run_test(t);
269 pr_debug("---- end ----\n%s:", tests[curr].desc); 265 pr_debug("---- end ----\n%s:", t->desc);
270 266
271 switch (err) { 267 switch (err) {
272 case TEST_OK: 268 case TEST_OK:
@@ -287,15 +283,15 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
287 283
288static int perf_test__list(int argc, const char **argv) 284static int perf_test__list(int argc, const char **argv)
289{ 285{
286 unsigned int j;
287 struct test *t;
290 int i = 0; 288 int i = 0;
291 289
292 while (tests[i].func) { 290 for_each_test(j, t) {
293 int curr = i++; 291 if (argc > 1 && !strstr(t->desc, argv[1]))
294
295 if (argc > 1 && !strstr(tests[curr].desc, argv[1]))
296 continue; 292 continue;
297 293
298 pr_info("%2d: %s\n", i, tests[curr].desc); 294 pr_info("%2d: %s\n", ++i, t->desc);
299 } 295 }
300 296
301 return 0; 297 return 0;
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 39c784a100a9..49b1959dda41 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -33,20 +33,20 @@ static unsigned int hex(char c)
33 return c - 'A' + 10; 33 return c - 'A' + 10;
34} 34}
35 35
36static void read_objdump_line(const char *line, size_t line_len, void **buf, 36static size_t read_objdump_line(const char *line, size_t line_len, void *buf,
37 size_t *len) 37 size_t len)
38{ 38{
39 const char *p; 39 const char *p;
40 size_t i; 40 size_t i, j = 0;
41 41
42 /* Skip to a colon */ 42 /* Skip to a colon */
43 p = strchr(line, ':'); 43 p = strchr(line, ':');
44 if (!p) 44 if (!p)
45 return; 45 return 0;
46 i = p + 1 - line; 46 i = p + 1 - line;
47 47
48 /* Read bytes */ 48 /* Read bytes */
49 while (*len) { 49 while (j < len) {
50 char c1, c2; 50 char c1, c2;
51 51
52 /* Skip spaces */ 52 /* Skip spaces */
@@ -65,20 +65,26 @@ static void read_objdump_line(const char *line, size_t line_len, void **buf,
65 if (i < line_len && line[i] && !isspace(line[i])) 65 if (i < line_len && line[i] && !isspace(line[i]))
66 break; 66 break;
67 /* Store byte */ 67 /* Store byte */
68 *(unsigned char *)*buf = (hex(c1) << 4) | hex(c2); 68 *(unsigned char *)buf = (hex(c1) << 4) | hex(c2);
69 *buf += 1; 69 buf += 1;
70 *len -= 1; 70 j++;
71 } 71 }
72 /* return number of successfully read bytes */
73 return j;
72} 74}
73 75
74static int read_objdump_output(FILE *f, void **buf, size_t *len) 76static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr)
75{ 77{
76 char *line = NULL; 78 char *line = NULL;
77 size_t line_len; 79 size_t line_len, off_last = 0;
78 ssize_t ret; 80 ssize_t ret;
79 int err = 0; 81 int err = 0;
82 u64 addr, last_addr = start_addr;
83
84 while (off_last < *len) {
85 size_t off, read_bytes, written_bytes;
86 unsigned char tmp[BUFSZ];
80 87
81 while (1) {
82 ret = getline(&line, &line_len, f); 88 ret = getline(&line, &line_len, f);
83 if (feof(f)) 89 if (feof(f))
84 break; 90 break;
@@ -87,9 +93,33 @@ static int read_objdump_output(FILE *f, void **buf, size_t *len)
87 err = -1; 93 err = -1;
88 break; 94 break;
89 } 95 }
90 read_objdump_line(line, ret, buf, len); 96
97 /* read objdump data into temporary buffer */
98 read_bytes = read_objdump_line(line, ret, tmp, sizeof(tmp));
99 if (!read_bytes)
100 continue;
101
102 if (sscanf(line, "%"PRIx64, &addr) != 1)
103 continue;
104 if (addr < last_addr) {
105 pr_debug("addr going backwards, read beyond section?\n");
106 break;
107 }
108 last_addr = addr;
109
110 /* copy it from temporary buffer to 'buf' according
111 * to address on current objdump line */
112 off = addr - start_addr;
113 if (off >= *len)
114 break;
115 written_bytes = MIN(read_bytes, *len - off);
116 memcpy(buf + off, tmp, written_bytes);
117 off_last = off + written_bytes;
91 } 118 }
92 119
120 /* len returns number of bytes that could not be read */
121 *len -= off_last;
122
93 free(line); 123 free(line);
94 124
95 return err; 125 return err;
@@ -103,7 +133,7 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf,
103 FILE *f; 133 FILE *f;
104 int ret; 134 int ret;
105 135
106 fmt = "%s -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s"; 136 fmt = "%s -z -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s";
107 ret = snprintf(cmd, sizeof(cmd), fmt, "objdump", addr, addr + len, 137 ret = snprintf(cmd, sizeof(cmd), fmt, "objdump", addr, addr + len,
108 filename); 138 filename);
109 if (ret <= 0 || (size_t)ret >= sizeof(cmd)) 139 if (ret <= 0 || (size_t)ret >= sizeof(cmd))
@@ -120,7 +150,7 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf,
120 return -1; 150 return -1;
121 } 151 }
122 152
123 ret = read_objdump_output(f, &buf, &len); 153 ret = read_objdump_output(f, buf, &len, addr);
124 if (len) { 154 if (len) {
125 pr_debug("objdump read too few bytes\n"); 155 pr_debug("objdump read too few bytes\n");
126 if (!ret) 156 if (!ret)
@@ -132,6 +162,18 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf,
132 return ret; 162 return ret;
133} 163}
134 164
165static void dump_buf(unsigned char *buf, size_t len)
166{
167 size_t i;
168
169 for (i = 0; i < len; i++) {
170 pr_debug("0x%02x ", buf[i]);
171 if (i % 16 == 15)
172 pr_debug("\n");
173 }
174 pr_debug("\n");
175}
176
135static int read_object_code(u64 addr, size_t len, u8 cpumode, 177static int read_object_code(u64 addr, size_t len, u8 cpumode,
136 struct thread *thread, struct state *state) 178 struct thread *thread, struct state *state)
137{ 179{
@@ -234,6 +276,10 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
234 /* The results should be identical */ 276 /* The results should be identical */
235 if (memcmp(buf1, buf2, len)) { 277 if (memcmp(buf1, buf2, len)) {
236 pr_debug("Bytes read differ from those read by objdump\n"); 278 pr_debug("Bytes read differ from those read by objdump\n");
279 pr_debug("buf1 (dso):\n");
280 dump_buf(buf1, len);
281 pr_debug("buf2 (objdump):\n");
282 dump_buf(buf2, len);
237 return -1; 283 return -1;
238 } 284 }
239 pr_debug("Bytes read match those read by objdump\n"); 285 pr_debug("Bytes read match those read by objdump\n");
@@ -427,7 +473,7 @@ static int do_test_code_reading(bool try_kcore)
427 symbol_conf.kallsyms_name = "/proc/kallsyms"; 473 symbol_conf.kallsyms_name = "/proc/kallsyms";
428 474
429 /* Load kernel map */ 475 /* Load kernel map */
430 map = machine->vmlinux_maps[MAP__FUNCTION]; 476 map = machine__kernel_map(machine);
431 ret = map__load(map, NULL); 477 ret = map__load(map, NULL);
432 if (ret < 0) { 478 if (ret < 0) {
433 pr_debug("map__load failed\n"); 479 pr_debug("map__load failed\n");
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index 40b36c462427..07221793a3ac 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -11,6 +11,10 @@
11#include "thread.h" 11#include "thread.h"
12#include "callchain.h" 12#include "callchain.h"
13 13
14#if defined (__x86_64__) || defined (__i386__)
15#include "arch-tests.h"
16#endif
17
14/* For bsearch. We try to unwind functions in shared object. */ 18/* For bsearch. We try to unwind functions in shared object. */
15#include <stdlib.h> 19#include <stdlib.h>
16 20
diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c
index 52162425c969..790e413d9a1f 100644
--- a/tools/perf/tests/evsel-tp-sched.c
+++ b/tools/perf/tests/evsel-tp-sched.c
@@ -1,3 +1,4 @@
1#include <linux/err.h>
1#include <traceevent/event-parse.h> 2#include <traceevent/event-parse.h>
2#include "evsel.h" 3#include "evsel.h"
3#include "tests.h" 4#include "tests.h"
@@ -36,8 +37,8 @@ int test__perf_evsel__tp_sched_test(void)
36 struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch"); 37 struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch");
37 int ret = 0; 38 int ret = 0;
38 39
39 if (evsel == NULL) { 40 if (IS_ERR(evsel)) {
40 pr_debug("perf_evsel__new\n"); 41 pr_debug("perf_evsel__newtp failed with %ld\n", PTR_ERR(evsel));
41 return -1; 42 return -1;
42 } 43 }
43 44
@@ -66,6 +67,11 @@ int test__perf_evsel__tp_sched_test(void)
66 67
67 evsel = perf_evsel__newtp("sched", "sched_wakeup"); 68 evsel = perf_evsel__newtp("sched", "sched_wakeup");
68 69
70 if (IS_ERR(evsel)) {
71 pr_debug("perf_evsel__newtp failed with %ld\n", PTR_ERR(evsel));
72 return -1;
73 }
74
69 if (perf_evsel__test_field(evsel, "comm", 16, true)) 75 if (perf_evsel__test_field(evsel, "comm", 16, true))
70 ret = -1; 76 ret = -1;
71 77
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c
index ce48775e6ada..818acf875dd0 100644
--- a/tools/perf/tests/hists_filter.c
+++ b/tools/perf/tests/hists_filter.c
@@ -16,30 +16,31 @@ struct sample {
16 struct thread *thread; 16 struct thread *thread;
17 struct map *map; 17 struct map *map;
18 struct symbol *sym; 18 struct symbol *sym;
19 int socket;
19}; 20};
20 21
21/* For the numbers, see hists_common.c */ 22/* For the numbers, see hists_common.c */
22static struct sample fake_samples[] = { 23static struct sample fake_samples[] = {
23 /* perf [kernel] schedule() */ 24 /* perf [kernel] schedule() */
24 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, }, 25 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, .socket = 0 },
25 /* perf [perf] main() */ 26 /* perf [perf] main() */
26 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_MAIN, }, 27 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_MAIN, .socket = 0 },
27 /* perf [libc] malloc() */ 28 /* perf [libc] malloc() */
28 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, }, 29 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, .socket = 0 },
29 /* perf [perf] main() */ 30 /* perf [perf] main() */
30 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, }, /* will be merged */ 31 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, .socket = 0 }, /* will be merged */
31 /* perf [perf] cmd_record() */ 32 /* perf [perf] cmd_record() */
32 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_CMD_RECORD, }, 33 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_CMD_RECORD, .socket = 1 },
33 /* perf [kernel] page_fault() */ 34 /* perf [kernel] page_fault() */
34 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_PAGE_FAULT, }, 35 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_PAGE_FAULT, .socket = 1 },
35 /* bash [bash] main() */ 36 /* bash [bash] main() */
36 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_MAIN, }, 37 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_MAIN, .socket = 2 },
37 /* bash [bash] xmalloc() */ 38 /* bash [bash] xmalloc() */
38 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_XMALLOC, }, 39 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_XMALLOC, .socket = 2 },
39 /* bash [libc] malloc() */ 40 /* bash [libc] malloc() */
40 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_MALLOC, }, 41 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_MALLOC, .socket = 3 },
41 /* bash [kernel] page_fault() */ 42 /* bash [kernel] page_fault() */
42 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_KERNEL_PAGE_FAULT, }, 43 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_KERNEL_PAGE_FAULT, .socket = 3 },
43}; 44};
44 45
45static int add_hist_entries(struct perf_evlist *evlist, 46static int add_hist_entries(struct perf_evlist *evlist,
@@ -83,6 +84,7 @@ static int add_hist_entries(struct perf_evlist *evlist,
83 &sample) < 0) 84 &sample) < 0)
84 goto out; 85 goto out;
85 86
87 al.socket = fake_samples[i].socket;
86 if (hist_entry_iter__add(&iter, &al, 88 if (hist_entry_iter__add(&iter, &al,
87 PERF_MAX_STACK_DEPTH, NULL) < 0) { 89 PERF_MAX_STACK_DEPTH, NULL) < 0) {
88 addr_location__put(&al); 90 addr_location__put(&al);
@@ -253,6 +255,39 @@ int test__hists_filter(void)
253 TEST_ASSERT_VAL("Unmatched total period for symbol filter", 255 TEST_ASSERT_VAL("Unmatched total period for symbol filter",
254 hists->stats.total_non_filtered_period == 300); 256 hists->stats.total_non_filtered_period == 300);
255 257
258 /* remove symbol filter first */
259 hists->symbol_filter_str = NULL;
260 hists__filter_by_symbol(hists);
261
262 /* now applying socket filters */
263 hists->socket_filter = 2;
264 hists__filter_by_socket(hists);
265
266 if (verbose > 2) {
267 pr_info("Histogram for socket filters\n");
268 print_hists_out(hists);
269 }
270
271 /* normal stats should be invariant */
272 TEST_ASSERT_VAL("Invalid nr samples",
273 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
274 TEST_ASSERT_VAL("Invalid nr hist entries",
275 hists->nr_entries == 9);
276 TEST_ASSERT_VAL("Invalid total period",
277 hists->stats.total_period == 1000);
278
279 /* but filter stats are changed */
280 TEST_ASSERT_VAL("Unmatched nr samples for socket filter",
281 hists->stats.nr_non_filtered_samples == 2);
282 TEST_ASSERT_VAL("Unmatched nr hist entries for socket filter",
283 hists->nr_non_filtered_entries == 2);
284 TEST_ASSERT_VAL("Unmatched total period for socket filter",
285 hists->stats.total_non_filtered_period == 200);
286
287 /* remove socket filter first */
288 hists->socket_filter = -1;
289 hists__filter_by_socket(hists);
290
256 /* now applying all filters at once. */ 291 /* now applying all filters at once. */
257 hists->thread_filter = fake_samples[1].thread; 292 hists->thread_filter = fake_samples[1].thread;
258 hists->dso_filter = fake_samples[1].map->dso; 293 hists->dso_filter = fake_samples[1].map->dso;
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index ba31c4bd441d..2cbd0c6901e3 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -44,6 +44,7 @@ make_no_libnuma := NO_LIBNUMA=1
44make_no_libaudit := NO_LIBAUDIT=1 44make_no_libaudit := NO_LIBAUDIT=1
45make_no_libbionic := NO_LIBBIONIC=1 45make_no_libbionic := NO_LIBBIONIC=1
46make_no_auxtrace := NO_AUXTRACE=1 46make_no_auxtrace := NO_AUXTRACE=1
47make_no_libbpf := NO_LIBBPF=1
47make_tags := tags 48make_tags := tags
48make_cscope := cscope 49make_cscope := cscope
49make_help := help 50make_help := help
@@ -66,7 +67,7 @@ make_static := LDFLAGS=-static
66make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 67make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
67make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 68make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
68make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 69make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
69make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 70make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
70 71
71# $(run) contains all available tests 72# $(run) contains all available tests
72run := make_pure 73run := make_pure
@@ -94,6 +95,7 @@ run += make_no_libnuma
94run += make_no_libaudit 95run += make_no_libaudit
95run += make_no_libbionic 96run += make_no_libbionic
96run += make_no_auxtrace 97run += make_no_auxtrace
98run += make_no_libbpf
97run += make_help 99run += make_help
98run += make_doc 100run += make_doc
99run += make_perf_o 101run += make_perf_o
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 666b67a4df9d..4495493c9431 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -3,6 +3,7 @@
3#include "thread_map.h" 3#include "thread_map.h"
4#include "cpumap.h" 4#include "cpumap.h"
5#include "tests.h" 5#include "tests.h"
6#include <linux/err.h>
6 7
7/* 8/*
8 * This test will generate random numbers of calls to some getpid syscalls, 9 * This test will generate random numbers of calls to some getpid syscalls,
@@ -65,7 +66,7 @@ int test__basic_mmap(void)
65 66
66 snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]); 67 snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
67 evsels[i] = perf_evsel__newtp("syscalls", name); 68 evsels[i] = perf_evsel__newtp("syscalls", name);
68 if (evsels[i] == NULL) { 69 if (IS_ERR(evsels[i])) {
69 pr_debug("perf_evsel__new\n"); 70 pr_debug("perf_evsel__new\n");
70 goto out_delete_evlist; 71 goto out_delete_evlist;
71 } 72 }
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index a572f87e9c8d..2006485a2859 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -1,3 +1,5 @@
1#include <api/fs/fs.h>
2#include <linux/err.h>
1#include "evsel.h" 3#include "evsel.h"
2#include "tests.h" 4#include "tests.h"
3#include "thread_map.h" 5#include "thread_map.h"
@@ -14,6 +16,7 @@ int test__openat_syscall_event_on_all_cpus(void)
14 cpu_set_t cpu_set; 16 cpu_set_t cpu_set;
15 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); 17 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
16 char sbuf[STRERR_BUFSIZE]; 18 char sbuf[STRERR_BUFSIZE];
19 char errbuf[BUFSIZ];
17 20
18 if (threads == NULL) { 21 if (threads == NULL) {
19 pr_debug("thread_map__new\n"); 22 pr_debug("thread_map__new\n");
@@ -29,13 +32,9 @@ int test__openat_syscall_event_on_all_cpus(void)
29 CPU_ZERO(&cpu_set); 32 CPU_ZERO(&cpu_set);
30 33
31 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); 34 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
32 if (evsel == NULL) { 35 if (IS_ERR(evsel)) {
33 if (tracefs_configured()) 36 tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "syscalls", "sys_enter_openat");
34 pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); 37 pr_debug("%s\n", errbuf);
35 else if (debugfs_configured())
36 pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
37 else
38 pr_debug("Neither tracefs or debugfs is enabled in this kernel\n");
39 goto out_thread_map_delete; 38 goto out_thread_map_delete;
40 } 39 }
41 40
diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c
index 01a19626c846..5e811cd8f1c3 100644
--- a/tools/perf/tests/openat-syscall-tp-fields.c
+++ b/tools/perf/tests/openat-syscall-tp-fields.c
@@ -1,3 +1,4 @@
1#include <linux/err.h>
1#include "perf.h" 2#include "perf.h"
2#include "evlist.h" 3#include "evlist.h"
3#include "evsel.h" 4#include "evsel.h"
@@ -30,7 +31,7 @@ int test__syscall_openat_tp_fields(void)
30 } 31 }
31 32
32 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); 33 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
33 if (evsel == NULL) { 34 if (IS_ERR(evsel)) {
34 pr_debug("%s: perf_evsel__newtp\n", __func__); 35 pr_debug("%s: perf_evsel__newtp\n", __func__);
35 goto out_delete_evlist; 36 goto out_delete_evlist;
36 } 37 }
@@ -88,7 +89,7 @@ int test__syscall_openat_tp_fields(void)
88 89
89 err = perf_evsel__parse_sample(evsel, event, &sample); 90 err = perf_evsel__parse_sample(evsel, event, &sample);
90 if (err) { 91 if (err) {
91 pr_err("Can't parse sample, err = %d\n", err); 92 pr_debug("Can't parse sample, err = %d\n", err);
92 goto out_delete_evlist; 93 goto out_delete_evlist;
93 } 94 }
94 95
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index c9a37bc6b33a..033b54797b8a 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -1,3 +1,5 @@
1#include <api/fs/tracing_path.h>
2#include <linux/err.h>
1#include "thread_map.h" 3#include "thread_map.h"
2#include "evsel.h" 4#include "evsel.h"
3#include "debug.h" 5#include "debug.h"
@@ -10,6 +12,7 @@ int test__openat_syscall_event(void)
10 unsigned int nr_openat_calls = 111, i; 12 unsigned int nr_openat_calls = 111, i;
11 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); 13 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
12 char sbuf[STRERR_BUFSIZE]; 14 char sbuf[STRERR_BUFSIZE];
15 char errbuf[BUFSIZ];
13 16
14 if (threads == NULL) { 17 if (threads == NULL) {
15 pr_debug("thread_map__new\n"); 18 pr_debug("thread_map__new\n");
@@ -17,13 +20,9 @@ int test__openat_syscall_event(void)
17 } 20 }
18 21
19 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); 22 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
20 if (evsel == NULL) { 23 if (IS_ERR(evsel)) {
21 if (tracefs_configured()) 24 tracing_path__strerror_open_tp(errno, errbuf, sizeof(errbuf), "syscalls", "sys_enter_openat");
22 pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); 25 pr_debug("%s\n", errbuf);
23 else if (debugfs_configured())
24 pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
25 else
26 pr_debug("Neither tracefs or debugfs is enabled in this kernel\n");
27 goto out_thread_map_delete; 26 goto out_thread_map_delete;
28 } 27 }
29 28
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 9b6b2b6324a1..636d7b42d844 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -3,11 +3,11 @@
3#include "evsel.h" 3#include "evsel.h"
4#include "evlist.h" 4#include "evlist.h"
5#include <api/fs/fs.h> 5#include <api/fs/fs.h>
6#include <api/fs/tracefs.h>
7#include <api/fs/debugfs.h>
8#include "tests.h" 6#include "tests.h"
9#include "debug.h" 7#include "debug.h"
8#include "util.h"
10#include <linux/hw_breakpoint.h> 9#include <linux/hw_breakpoint.h>
10#include <api/fs/fs.h>
11 11
12#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \ 12#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \
13 PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) 13 PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD)
@@ -1260,25 +1260,24 @@ test__checkevent_breakpoint_len_rw_modifier(struct perf_evlist *evlist)
1260 return test__checkevent_breakpoint_rw(evlist); 1260 return test__checkevent_breakpoint_rw(evlist);
1261} 1261}
1262 1262
1263static int test__checkevent_precise_max_modifier(struct perf_evlist *evlist)
1264{
1265 struct perf_evsel *evsel = perf_evlist__first(evlist);
1266
1267 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
1268 TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
1269 TEST_ASSERT_VAL("wrong config",
1270 PERF_COUNT_SW_TASK_CLOCK == evsel->attr.config);
1271 return 0;
1272}
1273
1263static int count_tracepoints(void) 1274static int count_tracepoints(void)
1264{ 1275{
1265 char events_path[PATH_MAX];
1266 struct dirent *events_ent; 1276 struct dirent *events_ent;
1267 const char *mountpoint;
1268 DIR *events_dir; 1277 DIR *events_dir;
1269 int cnt = 0; 1278 int cnt = 0;
1270 1279
1271 mountpoint = tracefs_find_mountpoint(); 1280 events_dir = opendir(tracing_events_path);
1272 if (mountpoint) {
1273 scnprintf(events_path, PATH_MAX, "%s/events",
1274 mountpoint);
1275 } else {
1276 mountpoint = debugfs_find_mountpoint();
1277 scnprintf(events_path, PATH_MAX, "%s/tracing/events",
1278 mountpoint);
1279 }
1280
1281 events_dir = opendir(events_path);
1282 1281
1283 TEST_ASSERT_VAL("Can't open events dir", events_dir); 1282 TEST_ASSERT_VAL("Can't open events dir", events_dir);
1284 1283
@@ -1295,7 +1294,7 @@ static int count_tracepoints(void)
1295 continue; 1294 continue;
1296 1295
1297 scnprintf(sys_path, PATH_MAX, "%s/%s", 1296 scnprintf(sys_path, PATH_MAX, "%s/%s",
1298 events_path, events_ent->d_name); 1297 tracing_events_path, events_ent->d_name);
1299 1298
1300 sys_dir = opendir(sys_path); 1299 sys_dir = opendir(sys_path);
1301 TEST_ASSERT_VAL("Can't open sys dir", sys_dir); 1300 TEST_ASSERT_VAL("Can't open sys dir", sys_dir);
@@ -1575,6 +1574,11 @@ static struct evlist_test test__events[] = {
1575 .check = test__checkevent_exclude_idle_modifier_1, 1574 .check = test__checkevent_exclude_idle_modifier_1,
1576 .id = 46, 1575 .id = 46,
1577 }, 1576 },
1577 {
1578 .name = "task-clock:P,cycles",
1579 .check = test__checkevent_precise_max_modifier,
1580 .id = 47,
1581 },
1578}; 1582};
1579 1583
1580static struct evlist_test test__events_pmu[] = { 1584static struct evlist_test test__events_pmu[] = {
@@ -1750,6 +1754,17 @@ static int test_pmu_events(void)
1750 return ret; 1754 return ret;
1751} 1755}
1752 1756
1757static void debug_warn(const char *warn, va_list params)
1758{
1759 char msg[1024];
1760
1761 if (!verbose)
1762 return;
1763
1764 vsnprintf(msg, sizeof(msg), warn, params);
1765 fprintf(stderr, " Warning: %s\n", msg);
1766}
1767
1753int test__parse_events(void) 1768int test__parse_events(void)
1754{ 1769{
1755 int ret1, ret2 = 0; 1770 int ret1, ret2 = 0;
@@ -1761,6 +1776,8 @@ do { \
1761 ret2 = ret1; \ 1776 ret2 = ret1; \
1762} while (0) 1777} while (0)
1763 1778
1779 set_warning_routine(debug_warn);
1780
1764 TEST_EVENTS(test__events); 1781 TEST_EVENTS(test__events);
1765 1782
1766 if (test_pmu()) 1783 if (test_pmu())
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 1aa21c90731b..5b83f56a3b6f 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -34,6 +34,8 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
34 .disabled = 1, 34 .disabled = 1,
35 .freq = 1, 35 .freq = 1,
36 }; 36 };
37 struct cpu_map *cpus;
38 struct thread_map *threads;
37 39
38 attr.sample_freq = 500; 40 attr.sample_freq = 500;
39 41
@@ -50,14 +52,19 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
50 } 52 }
51 perf_evlist__add(evlist, evsel); 53 perf_evlist__add(evlist, evsel);
52 54
53 evlist->cpus = cpu_map__dummy_new(); 55 cpus = cpu_map__dummy_new();
54 evlist->threads = thread_map__new_by_tid(getpid()); 56 threads = thread_map__new_by_tid(getpid());
55 if (!evlist->cpus || !evlist->threads) { 57 if (!cpus || !threads) {
56 err = -ENOMEM; 58 err = -ENOMEM;
57 pr_debug("Not enough memory to create thread/cpu maps\n"); 59 pr_debug("Not enough memory to create thread/cpu maps\n");
58 goto out_delete_evlist; 60 goto out_free_maps;
59 } 61 }
60 62
63 perf_evlist__set_maps(evlist, cpus, threads);
64
65 cpus = NULL;
66 threads = NULL;
67
61 if (perf_evlist__open(evlist)) { 68 if (perf_evlist__open(evlist)) {
62 const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate"; 69 const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";
63 70
@@ -107,6 +114,9 @@ next_event:
107 err = -1; 114 err = -1;
108 } 115 }
109 116
117out_free_maps:
118 cpu_map__put(cpus);
119 thread_map__put(threads);
110out_delete_evlist: 120out_delete_evlist:
111 perf_evlist__delete(evlist); 121 perf_evlist__delete(evlist);
112 return err; 122 return err;
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 3a8fedef83bc..add16385f13e 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -43,6 +43,8 @@ int test__task_exit(void)
43 }; 43 };
44 const char *argv[] = { "true", NULL }; 44 const char *argv[] = { "true", NULL };
45 char sbuf[STRERR_BUFSIZE]; 45 char sbuf[STRERR_BUFSIZE];
46 struct cpu_map *cpus;
47 struct thread_map *threads;
46 48
47 signal(SIGCHLD, sig_handler); 49 signal(SIGCHLD, sig_handler);
48 50
@@ -58,14 +60,19 @@ int test__task_exit(void)
58 * perf_evlist__prepare_workload we'll fill in the only thread 60 * perf_evlist__prepare_workload we'll fill in the only thread
59 * we're monitoring, the one forked there. 61 * we're monitoring, the one forked there.
60 */ 62 */
61 evlist->cpus = cpu_map__dummy_new(); 63 cpus = cpu_map__dummy_new();
62 evlist->threads = thread_map__new_by_tid(-1); 64 threads = thread_map__new_by_tid(-1);
63 if (!evlist->cpus || !evlist->threads) { 65 if (!cpus || !threads) {
64 err = -ENOMEM; 66 err = -ENOMEM;
65 pr_debug("Not enough memory to create thread/cpu maps\n"); 67 pr_debug("Not enough memory to create thread/cpu maps\n");
66 goto out_delete_evlist; 68 goto out_free_maps;
67 } 69 }
68 70
71 perf_evlist__set_maps(evlist, cpus, threads);
72
73 cpus = NULL;
74 threads = NULL;
75
69 err = perf_evlist__prepare_workload(evlist, &target, argv, false, 76 err = perf_evlist__prepare_workload(evlist, &target, argv, false,
70 workload_exec_failed_signal); 77 workload_exec_failed_signal);
71 if (err < 0) { 78 if (err < 0) {
@@ -114,6 +121,9 @@ retry:
114 err = -1; 121 err = -1;
115 } 122 }
116 123
124out_free_maps:
125 cpu_map__put(cpus);
126 thread_map__put(threads);
117out_delete_evlist: 127out_delete_evlist:
118 perf_evlist__delete(evlist); 128 perf_evlist__delete(evlist);
119 return err; 129 return err;
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index bf113a247987..c80486969f83 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -24,13 +24,17 @@ enum {
24 TEST_SKIP = -2, 24 TEST_SKIP = -2,
25}; 25};
26 26
27struct test {
28 const char *desc;
29 int (*func)(void);
30};
31
27/* Tests */ 32/* Tests */
28int test__vmlinux_matches_kallsyms(void); 33int test__vmlinux_matches_kallsyms(void);
29int test__openat_syscall_event(void); 34int test__openat_syscall_event(void);
30int test__openat_syscall_event_on_all_cpus(void); 35int test__openat_syscall_event_on_all_cpus(void);
31int test__basic_mmap(void); 36int test__basic_mmap(void);
32int test__PERF_RECORD(void); 37int test__PERF_RECORD(void);
33int test__rdpmc(void);
34int test__perf_evsel__roundtrip_name_test(void); 38int test__perf_evsel__roundtrip_name_test(void);
35int test__perf_evsel__tp_sched_test(void); 39int test__perf_evsel__tp_sched_test(void);
36int test__syscall_openat_tp_fields(void); 40int test__syscall_openat_tp_fields(void);
@@ -46,7 +50,6 @@ int test__bp_signal(void);
46int test__bp_signal_overflow(void); 50int test__bp_signal_overflow(void);
47int test__task_exit(void); 51int test__task_exit(void);
48int test__sw_clock_freq(void); 52int test__sw_clock_freq(void);
49int test__perf_time_to_tsc(void);
50int test__code_reading(void); 53int test__code_reading(void);
51int test__sample_parsing(void); 54int test__sample_parsing(void);
52int test__keep_tracking(void); 55int test__keep_tracking(void);
@@ -63,8 +66,9 @@ int test__fdarray__add(void);
63int test__kmod_path__parse(void); 66int test__kmod_path__parse(void);
64int test__thread_map(void); 67int test__thread_map(void);
65int test__llvm(void); 68int test__llvm(void);
69int test_session_topology(void);
66 70
67#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__) 71#if defined(__arm__) || defined(__aarch64__)
68#ifdef HAVE_DWARF_UNWIND_SUPPORT 72#ifdef HAVE_DWARF_UNWIND_SUPPORT
69struct thread; 73struct thread;
70struct perf_sample; 74struct perf_sample;
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
new file mode 100644
index 000000000000..f5bb096c3bd9
--- /dev/null
+++ b/tools/perf/tests/topology.c
@@ -0,0 +1,115 @@
1#include <string.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include "tests.h"
5#include "util.h"
6#include "session.h"
7#include "evlist.h"
8#include "debug.h"
9
10#define TEMPL "/tmp/perf-test-XXXXXX"
11#define DATA_SIZE 10
12
13static int get_temp(char *path)
14{
15 int fd;
16
17 strcpy(path, TEMPL);
18
19 fd = mkstemp(path);
20 if (fd < 0) {
21 perror("mkstemp failed");
22 return -1;
23 }
24
25 close(fd);
26 return 0;
27}
28
29static int session_write_header(char *path)
30{
31 struct perf_session *session;
32 struct perf_data_file file = {
33 .path = path,
34 .mode = PERF_DATA_MODE_WRITE,
35 };
36
37 session = perf_session__new(&file, false, NULL);
38 TEST_ASSERT_VAL("can't get session", session);
39
40 session->evlist = perf_evlist__new_default();
41 TEST_ASSERT_VAL("can't get evlist", session->evlist);
42
43 perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
44 perf_header__set_feat(&session->header, HEADER_NRCPUS);
45
46 session->header.data_size += DATA_SIZE;
47
48 TEST_ASSERT_VAL("failed to write header",
49 !perf_session__write_header(session, session->evlist, file.fd, true));
50
51 perf_session__delete(session);
52
53 return 0;
54}
55
56static int check_cpu_topology(char *path, struct cpu_map *map)
57{
58 struct perf_session *session;
59 struct perf_data_file file = {
60 .path = path,
61 .mode = PERF_DATA_MODE_READ,
62 };
63 int i;
64
65 session = perf_session__new(&file, false, NULL);
66 TEST_ASSERT_VAL("can't get session", session);
67
68 for (i = 0; i < session->header.env.nr_cpus_online; i++) {
69 pr_debug("CPU %d, core %d, socket %d\n", i,
70 session->header.env.cpu[i].core_id,
71 session->header.env.cpu[i].socket_id);
72 }
73
74 for (i = 0; i < map->nr; i++) {
75 TEST_ASSERT_VAL("Core ID doesn't match",
76 (session->header.env.cpu[map->map[i]].core_id == (cpu_map__get_core(map, i, NULL) & 0xffff)));
77
78 TEST_ASSERT_VAL("Socket ID doesn't match",
79 (session->header.env.cpu[map->map[i]].socket_id == cpu_map__get_socket(map, i, NULL)));
80 }
81
82 perf_session__delete(session);
83
84 return 0;
85}
86
87int test_session_topology(void)
88{
89 char path[PATH_MAX];
90 struct cpu_map *map;
91 int ret = -1;
92
93 TEST_ASSERT_VAL("can't get templ file", !get_temp(path));
94
95 pr_debug("templ file: %s\n", path);
96
97 if (session_write_header(path))
98 goto free_path;
99
100 map = cpu_map__new(NULL);
101 if (map == NULL) {
102 pr_debug("failed to get system cpumap\n");
103 goto free_path;
104 }
105
106 if (check_cpu_topology(path, map))
107 goto free_map;
108 ret = 0;
109
110free_map:
111 cpu_map__put(map);
112free_path:
113 unlink(path);
114 return ret;
115}
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
index b34c5fc829ae..d677e018e504 100644
--- a/tools/perf/tests/vmlinux-kallsyms.c
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -68,7 +68,7 @@ int test__vmlinux_matches_kallsyms(void)
68 * to see if the running kernel was relocated by checking if it has the 68 * to see if the running kernel was relocated by checking if it has the
69 * same value in the vmlinux file we load. 69 * same value in the vmlinux file we load.
70 */ 70 */
71 kallsyms_map = machine__kernel_map(&kallsyms, type); 71 kallsyms_map = machine__kernel_map(&kallsyms);
72 72
73 /* 73 /*
74 * Step 5: 74 * Step 5:
@@ -80,7 +80,7 @@ int test__vmlinux_matches_kallsyms(void)
80 goto out; 80 goto out;
81 } 81 }
82 82
83 vmlinux_map = machine__kernel_map(&vmlinux, type); 83 vmlinux_map = machine__kernel_map(&vmlinux);
84 84
85 /* 85 /*
86 * Step 6: 86 * Step 6:
diff --git a/tools/perf/trace/strace/groups/file b/tools/perf/trace/strace/groups/file
index 62378a899d79..722e25d200bf 100644
--- a/tools/perf/trace/strace/groups/file
+++ b/tools/perf/trace/strace/groups/file
@@ -9,6 +9,7 @@ mkdir
9open 9open
10openat 10openat
11quotactl 11quotactl
12read
12readlink 13readlink
13rename 14rename
14rmdir 15rmdir
@@ -16,3 +17,4 @@ stat
16statfs 17statfs
17symlink 18symlink
18unlink 19unlink
20write
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index c6c7e5189214..e9703c0829f1 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -393,6 +393,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
393 393
394 if (browser->use_navkeypressed && !browser->navkeypressed) { 394 if (browser->use_navkeypressed && !browser->navkeypressed) {
395 if (key == K_DOWN || key == K_UP || 395 if (key == K_DOWN || key == K_UP ||
396 (browser->columns && (key == K_LEFT || key == K_RIGHT)) ||
396 key == K_PGDN || key == K_PGUP || 397 key == K_PGDN || key == K_PGUP ||
397 key == K_HOME || key == K_END || 398 key == K_HOME || key == K_END ||
398 key == ' ') { 399 key == ' ') {
@@ -421,6 +422,18 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
421 browser->seek(browser, -1, SEEK_CUR); 422 browser->seek(browser, -1, SEEK_CUR);
422 } 423 }
423 break; 424 break;
425 case K_RIGHT:
426 if (!browser->columns)
427 goto out;
428 if (browser->horiz_scroll < browser->columns - 1)
429 ++browser->horiz_scroll;
430 break;
431 case K_LEFT:
432 if (!browser->columns)
433 goto out;
434 if (browser->horiz_scroll != 0)
435 --browser->horiz_scroll;
436 break;
424 case K_PGDN: 437 case K_PGDN:
425 case ' ': 438 case ' ':
426 if (browser->top_idx + browser->rows > browser->nr_entries - 1) 439 if (browser->top_idx + browser->rows > browser->nr_entries - 1)
@@ -459,6 +472,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
459 browser->seek(browser, -offset, SEEK_END); 472 browser->seek(browser, -offset, SEEK_END);
460 break; 473 break;
461 default: 474 default:
475 out:
462 return key; 476 return key;
463 } 477 }
464 } 478 }
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index f3cef564de02..01781de59532 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -14,7 +14,7 @@
14struct ui_browser { 14struct ui_browser {
15 u64 index, top_idx; 15 u64 index, top_idx;
16 void *top, *entries; 16 void *top, *entries;
17 u16 y, x, width, height, rows; 17 u16 y, x, width, height, rows, columns, horiz_scroll;
18 int current_color; 18 int current_color;
19 void *priv; 19 void *priv;
20 const char *title; 20 const char *title;
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 29739b347599..d4d7cc27252f 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -768,8 +768,8 @@ static int annotate_browser__run(struct annotate_browser *browser,
768 "UP/DOWN/PGUP\n" 768 "UP/DOWN/PGUP\n"
769 "PGDN/SPACE Navigate\n" 769 "PGDN/SPACE Navigate\n"
770 "q/ESC/CTRL+C Exit\n\n" 770 "q/ESC/CTRL+C Exit\n\n"
771 "-> Go to target\n" 771 "ENTER Go to target\n"
772 "<- Exit\n" 772 "ESC Exit\n"
773 "H Cycle thru hottest instructions\n" 773 "H Cycle thru hottest instructions\n"
774 "j Toggle showing jump to target arrows\n" 774 "j Toggle showing jump to target arrows\n"
775 "J Toggle showing number of jump sources on targets\n" 775 "J Toggle showing number of jump sources on targets\n"
@@ -1056,7 +1056,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
1056 goto out_free_offsets; 1056 goto out_free_offsets;
1057 } 1057 }
1058 1058
1059 ui_helpline__push("Press <- or ESC to exit"); 1059 ui_helpline__push("Press ESC to exit");
1060 1060
1061 notes = symbol__annotation(sym); 1061 notes = symbol__annotation(sym);
1062 browser.start = map__rip_2objdump(map, sym->start); 1062 browser.start = map__rip_2objdump(map, sym->start);
@@ -1125,8 +1125,8 @@ static struct annotate_config {
1125 ANNOTATE_CFG(jump_arrows), 1125 ANNOTATE_CFG(jump_arrows),
1126 ANNOTATE_CFG(show_linenr), 1126 ANNOTATE_CFG(show_linenr),
1127 ANNOTATE_CFG(show_nr_jumps), 1127 ANNOTATE_CFG(show_nr_jumps),
1128 ANNOTATE_CFG(use_offset),
1129 ANNOTATE_CFG(show_total_period), 1128 ANNOTATE_CFG(show_total_period),
1129 ANNOTATE_CFG(use_offset),
1130}; 1130};
1131 1131
1132#undef ANNOTATE_CFG 1132#undef ANNOTATE_CFG
@@ -1152,9 +1152,9 @@ static int annotate__config(const char *var, const char *value,
1152 sizeof(struct annotate_config), annotate_config__cmp); 1152 sizeof(struct annotate_config), annotate_config__cmp);
1153 1153
1154 if (cfg == NULL) 1154 if (cfg == NULL)
1155 return -1; 1155 ui__warning("%s variable unknown, ignoring...", var);
1156 1156 else
1157 *cfg->value = perf_config_bool(name, value); 1157 *cfg->value = perf_config_bool(name, value);
1158 return 0; 1158 return 0;
1159} 1159}
1160 1160
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index cf86f2d3a5e7..e5afb8936040 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -784,11 +784,12 @@ static int hist_browser__show_entry(struct hist_browser *browser,
784 .size = sizeof(s), 784 .size = sizeof(s),
785 .ptr = &arg, 785 .ptr = &arg,
786 }; 786 };
787 int column = 0;
787 788
788 hist_browser__gotorc(browser, row, 0); 789 hist_browser__gotorc(browser, row, 0);
789 790
790 perf_hpp__for_each_format(fmt) { 791 perf_hpp__for_each_format(fmt) {
791 if (perf_hpp__should_skip(fmt)) 792 if (perf_hpp__should_skip(fmt) || column++ < browser->b.horiz_scroll)
792 continue; 793 continue;
793 794
794 if (current_entry && browser->b.navkeypressed) { 795 if (current_entry && browser->b.navkeypressed) {
@@ -861,14 +862,16 @@ static int advance_hpp_check(struct perf_hpp *hpp, int inc)
861 return hpp->size <= 0; 862 return hpp->size <= 0;
862} 863}
863 864
864static int hists__scnprintf_headers(char *buf, size_t size, struct hists *hists) 865static int hists_browser__scnprintf_headers(struct hist_browser *browser, char *buf, size_t size)
865{ 866{
867 struct hists *hists = browser->hists;
866 struct perf_hpp dummy_hpp = { 868 struct perf_hpp dummy_hpp = {
867 .buf = buf, 869 .buf = buf,
868 .size = size, 870 .size = size,
869 }; 871 };
870 struct perf_hpp_fmt *fmt; 872 struct perf_hpp_fmt *fmt;
871 size_t ret = 0; 873 size_t ret = 0;
874 int column = 0;
872 875
873 if (symbol_conf.use_callchain) { 876 if (symbol_conf.use_callchain) {
874 ret = scnprintf(buf, size, " "); 877 ret = scnprintf(buf, size, " ");
@@ -877,7 +880,7 @@ static int hists__scnprintf_headers(char *buf, size_t size, struct hists *hists)
877 } 880 }
878 881
879 perf_hpp__for_each_format(fmt) { 882 perf_hpp__for_each_format(fmt) {
880 if (perf_hpp__should_skip(fmt)) 883 if (perf_hpp__should_skip(fmt) || column++ < browser->b.horiz_scroll)
881 continue; 884 continue;
882 885
883 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); 886 ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists));
@@ -896,7 +899,7 @@ static void hist_browser__show_headers(struct hist_browser *browser)
896{ 899{
897 char headers[1024]; 900 char headers[1024];
898 901
899 hists__scnprintf_headers(headers, sizeof(headers), browser->hists); 902 hists_browser__scnprintf_headers(browser, headers, sizeof(headers));
900 ui_browser__gotorc(&browser->b, 0, 0); 903 ui_browser__gotorc(&browser->b, 0, 0);
901 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); 904 ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
902 ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); 905 ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1);
@@ -1261,6 +1264,7 @@ static int hists__browser_title(struct hists *hists,
1261 int printed; 1264 int printed;
1262 const struct dso *dso = hists->dso_filter; 1265 const struct dso *dso = hists->dso_filter;
1263 const struct thread *thread = hists->thread_filter; 1266 const struct thread *thread = hists->thread_filter;
1267 int socket_id = hists->socket_filter;
1264 unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; 1268 unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
1265 u64 nr_events = hists->stats.total_period; 1269 u64 nr_events = hists->stats.total_period;
1266 struct perf_evsel *evsel = hists_to_evsel(hists); 1270 struct perf_evsel *evsel = hists_to_evsel(hists);
@@ -1314,6 +1318,9 @@ static int hists__browser_title(struct hists *hists,
1314 if (dso) 1318 if (dso)
1315 printed += scnprintf(bf + printed, size - printed, 1319 printed += scnprintf(bf + printed, size - printed,
1316 ", DSO: %s", dso->short_name); 1320 ", DSO: %s", dso->short_name);
1321 if (socket_id > -1)
1322 printed += scnprintf(bf + printed, size - printed,
1323 ", Processor Socket: %d", socket_id);
1317 if (!is_report_browser(hbt)) { 1324 if (!is_report_browser(hbt)) {
1318 struct perf_top *top = hbt->arg; 1325 struct perf_top *top = hbt->arg;
1319 1326
@@ -1425,6 +1432,7 @@ struct popup_action {
1425 struct thread *thread; 1432 struct thread *thread;
1426 struct dso *dso; 1433 struct dso *dso;
1427 struct map_symbol ms; 1434 struct map_symbol ms;
1435 int socket;
1428 1436
1429 int (*fn)(struct hist_browser *browser, struct popup_action *act); 1437 int (*fn)(struct hist_browser *browser, struct popup_action *act);
1430}; 1438};
@@ -1437,7 +1445,7 @@ do_annotate(struct hist_browser *browser, struct popup_action *act)
1437 struct hist_entry *he; 1445 struct hist_entry *he;
1438 int err; 1446 int err;
1439 1447
1440 if (!objdump_path && perf_session_env__lookup_objdump(browser->env)) 1448 if (!objdump_path && perf_env__lookup_objdump(browser->env))
1441 return 0; 1449 return 0;
1442 1450
1443 notes = symbol__annotation(act->ms.sym); 1451 notes = symbol__annotation(act->ms.sym);
@@ -1488,7 +1496,7 @@ do_zoom_thread(struct hist_browser *browser, struct popup_action *act)
1488 thread__zput(browser->hists->thread_filter); 1496 thread__zput(browser->hists->thread_filter);
1489 ui_helpline__pop(); 1497 ui_helpline__pop();
1490 } else { 1498 } else {
1491 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"", 1499 ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s(%d) thread\"",
1492 thread->comm_set ? thread__comm_str(thread) : "", 1500 thread->comm_set ? thread__comm_str(thread) : "",
1493 thread->tid); 1501 thread->tid);
1494 browser->hists->thread_filter = thread__get(thread); 1502 browser->hists->thread_filter = thread__get(thread);
@@ -1522,7 +1530,7 @@ add_thread_opt(struct hist_browser *browser, struct popup_action *act,
1522static int 1530static int
1523do_zoom_dso(struct hist_browser *browser, struct popup_action *act) 1531do_zoom_dso(struct hist_browser *browser, struct popup_action *act)
1524{ 1532{
1525 struct dso *dso = act->dso; 1533 struct map *map = act->ms.map;
1526 1534
1527 if (browser->hists->dso_filter) { 1535 if (browser->hists->dso_filter) {
1528 pstack__remove(browser->pstack, &browser->hists->dso_filter); 1536 pstack__remove(browser->pstack, &browser->hists->dso_filter);
@@ -1530,11 +1538,11 @@ do_zoom_dso(struct hist_browser *browser, struct popup_action *act)
1530 browser->hists->dso_filter = NULL; 1538 browser->hists->dso_filter = NULL;
1531 ui_helpline__pop(); 1539 ui_helpline__pop();
1532 } else { 1540 } else {
1533 if (dso == NULL) 1541 if (map == NULL)
1534 return 0; 1542 return 0;
1535 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"", 1543 ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"",
1536 dso->kernel ? "the Kernel" : dso->short_name); 1544 __map__is_kernel(map) ? "the Kernel" : map->dso->short_name);
1537 browser->hists->dso_filter = dso; 1545 browser->hists->dso_filter = map->dso;
1538 perf_hpp__set_elide(HISTC_DSO, true); 1546 perf_hpp__set_elide(HISTC_DSO, true);
1539 pstack__push(browser->pstack, &browser->hists->dso_filter); 1547 pstack__push(browser->pstack, &browser->hists->dso_filter);
1540 } 1548 }
@@ -1546,17 +1554,18 @@ do_zoom_dso(struct hist_browser *browser, struct popup_action *act)
1546 1554
1547static int 1555static int
1548add_dso_opt(struct hist_browser *browser, struct popup_action *act, 1556add_dso_opt(struct hist_browser *browser, struct popup_action *act,
1549 char **optstr, struct dso *dso) 1557 char **optstr, struct map *map)
1550{ 1558{
1551 if (dso == NULL) 1559 if (map == NULL)
1552 return 0; 1560 return 0;
1553 1561
1554 if (asprintf(optstr, "Zoom %s %s DSO", 1562 if (asprintf(optstr, "Zoom %s %s DSO",
1555 browser->hists->dso_filter ? "out of" : "into", 1563 browser->hists->dso_filter ? "out of" : "into",
1556 dso->kernel ? "the Kernel" : dso->short_name) < 0) 1564 __map__is_kernel(map) ? "the Kernel" : map->dso->short_name) < 0)
1557 return 0; 1565 return 0;
1558 1566
1559 act->dso = dso; 1567 act->ms.map = map;
1568 act->dso = map->dso;
1560 act->fn = do_zoom_dso; 1569 act->fn = do_zoom_dso;
1561 return 1; 1570 return 1;
1562} 1571}
@@ -1672,6 +1681,41 @@ add_exit_opt(struct hist_browser *browser __maybe_unused,
1672 return 1; 1681 return 1;
1673} 1682}
1674 1683
1684static int
1685do_zoom_socket(struct hist_browser *browser, struct popup_action *act)
1686{
1687 if (browser->hists->socket_filter > -1) {
1688 pstack__remove(browser->pstack, &browser->hists->socket_filter);
1689 browser->hists->socket_filter = -1;
1690 perf_hpp__set_elide(HISTC_SOCKET, false);
1691 } else {
1692 browser->hists->socket_filter = act->socket;
1693 perf_hpp__set_elide(HISTC_SOCKET, true);
1694 pstack__push(browser->pstack, &browser->hists->socket_filter);
1695 }
1696
1697 hists__filter_by_socket(browser->hists);
1698 hist_browser__reset(browser);
1699 return 0;
1700}
1701
1702static int
1703add_socket_opt(struct hist_browser *browser, struct popup_action *act,
1704 char **optstr, int socket_id)
1705{
1706 if (socket_id < 0)
1707 return 0;
1708
1709 if (asprintf(optstr, "Zoom %s Processor Socket %d",
1710 (browser->hists->socket_filter > -1) ? "out of" : "into",
1711 socket_id) < 0)
1712 return 0;
1713
1714 act->socket = socket_id;
1715 act->fn = do_zoom_socket;
1716 return 1;
1717}
1718
1675static void hist_browser__update_nr_entries(struct hist_browser *hb) 1719static void hist_browser__update_nr_entries(struct hist_browser *hb)
1676{ 1720{
1677 u64 nr_entries = 0; 1721 u64 nr_entries = 0;
@@ -1717,14 +1761,16 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1717 "For multiple event sessions:\n\n" \ 1761 "For multiple event sessions:\n\n" \
1718 "TAB/UNTAB Switch events\n\n" \ 1762 "TAB/UNTAB Switch events\n\n" \
1719 "For symbolic views (--sort has sym):\n\n" \ 1763 "For symbolic views (--sort has sym):\n\n" \
1720 "-> Zoom into DSO/Threads & Annotate current symbol\n" \ 1764 "ENTER Zoom into DSO/Threads & Annotate current symbol\n" \
1721 "<- Zoom out\n" \ 1765 "ESC Zoom out\n" \
1722 "a Annotate current symbol\n" \ 1766 "a Annotate current symbol\n" \
1723 "C Collapse all callchains\n" \ 1767 "C Collapse all callchains\n" \
1724 "d Zoom into current DSO\n" \ 1768 "d Zoom into current DSO\n" \
1725 "E Expand all callchains\n" \ 1769 "E Expand all callchains\n" \
1726 "F Toggle percentage of filtered entries\n" \ 1770 "F Toggle percentage of filtered entries\n" \
1727 "H Display column headers\n" \ 1771 "H Display column headers\n" \
1772 "m Display context menu\n" \
1773 "S Zoom into current Processor Socket\n" \
1728 1774
1729 /* help messages are sorted by lexical order of the hotkey */ 1775 /* help messages are sorted by lexical order of the hotkey */
1730 const char report_help[] = HIST_BROWSER_HELP_COMMON 1776 const char report_help[] = HIST_BROWSER_HELP_COMMON
@@ -1755,7 +1801,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1755 hist_browser__update_nr_entries(browser); 1801 hist_browser__update_nr_entries(browser);
1756 } 1802 }
1757 1803
1758 browser->pstack = pstack__new(2); 1804 browser->pstack = pstack__new(3);
1759 if (browser->pstack == NULL) 1805 if (browser->pstack == NULL)
1760 goto out; 1806 goto out;
1761 1807
@@ -1764,8 +1810,17 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1764 memset(options, 0, sizeof(options)); 1810 memset(options, 0, sizeof(options));
1765 memset(actions, 0, sizeof(actions)); 1811 memset(actions, 0, sizeof(actions));
1766 1812
1767 perf_hpp__for_each_format(fmt) 1813 perf_hpp__for_each_format(fmt) {
1768 perf_hpp__reset_width(fmt, hists); 1814 perf_hpp__reset_width(fmt, hists);
1815 /*
1816 * This is done just once, and activates the horizontal scrolling
1817 * code in the ui_browser code, it would be better to have a the
1818 * counter in the perf_hpp code, but I couldn't find doing it here
1819 * works, FIXME by setting this in hist_browser__new, for now, be
1820 * clever 8-)
1821 */
1822 ++browser->b.columns;
1823 }
1769 1824
1770 if (symbol_conf.col_width_list_str) 1825 if (symbol_conf.col_width_list_str)
1771 perf_hpp__set_user_width(symbol_conf.col_width_list_str); 1826 perf_hpp__set_user_width(symbol_conf.col_width_list_str);
@@ -1773,7 +1828,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1773 while (1) { 1828 while (1) {
1774 struct thread *thread = NULL; 1829 struct thread *thread = NULL;
1775 struct dso *dso = NULL; 1830 struct dso *dso = NULL;
1831 struct map *map = NULL;
1776 int choice = 0; 1832 int choice = 0;
1833 int socked_id = -1;
1777 1834
1778 nr_options = 0; 1835 nr_options = 0;
1779 1836
@@ -1781,7 +1838,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1781 1838
1782 if (browser->he_selection != NULL) { 1839 if (browser->he_selection != NULL) {
1783 thread = hist_browser__selected_thread(browser); 1840 thread = hist_browser__selected_thread(browser);
1784 dso = browser->selection->map ? browser->selection->map->dso : NULL; 1841 map = browser->selection->map;
1842 if (map)
1843 dso = map->dso;
1844 socked_id = browser->he_selection->socket;
1785 } 1845 }
1786 switch (key) { 1846 switch (key) {
1787 case K_TAB: 1847 case K_TAB:
@@ -1824,9 +1884,14 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1824 actions->thread = thread; 1884 actions->thread = thread;
1825 do_zoom_thread(browser, actions); 1885 do_zoom_thread(browser, actions);
1826 continue; 1886 continue;
1887 case 'S':
1888 actions->socket = socked_id;
1889 do_zoom_socket(browser, actions);
1890 continue;
1827 case '/': 1891 case '/':
1828 if (ui_browser__input_window("Symbol to show", 1892 if (ui_browser__input_window("Symbol to show",
1829 "Please enter the name of symbol you want to see", 1893 "Please enter the name of symbol you want to see.\n"
1894 "To remove the filter later, press / + ENTER.",
1830 buf, "ENTER: OK, ESC: Cancel", 1895 buf, "ENTER: OK, ESC: Cancel",
1831 delay_secs * 2) == K_ENTER) { 1896 delay_secs * 2) == K_ENTER) {
1832 hists->symbol_filter_str = *buf ? buf : NULL; 1897 hists->symbol_filter_str = *buf ? buf : NULL;
@@ -1871,6 +1936,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1871 continue; 1936 continue;
1872 case K_ENTER: 1937 case K_ENTER:
1873 case K_RIGHT: 1938 case K_RIGHT:
1939 case 'm':
1874 /* menu */ 1940 /* menu */
1875 break; 1941 break;
1876 case K_ESC: 1942 case K_ESC:
@@ -1899,9 +1965,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1899 * Ditto for thread below. 1965 * Ditto for thread below.
1900 */ 1966 */
1901 do_zoom_dso(browser, actions); 1967 do_zoom_dso(browser, actions);
1902 } 1968 } else if (top == &browser->hists->thread_filter) {
1903 if (top == &browser->hists->thread_filter)
1904 do_zoom_thread(browser, actions); 1969 do_zoom_thread(browser, actions);
1970 } else if (top == &browser->hists->socket_filter) {
1971 do_zoom_socket(browser, actions);
1972 }
1905 continue; 1973 continue;
1906 } 1974 }
1907 case 'q': 1975 case 'q':
@@ -1965,17 +2033,29 @@ skip_annotation:
1965 nr_options += add_thread_opt(browser, &actions[nr_options], 2033 nr_options += add_thread_opt(browser, &actions[nr_options],
1966 &options[nr_options], thread); 2034 &options[nr_options], thread);
1967 nr_options += add_dso_opt(browser, &actions[nr_options], 2035 nr_options += add_dso_opt(browser, &actions[nr_options],
1968 &options[nr_options], dso); 2036 &options[nr_options], map);
1969 nr_options += add_map_opt(browser, &actions[nr_options], 2037 nr_options += add_map_opt(browser, &actions[nr_options],
1970 &options[nr_options], 2038 &options[nr_options],
1971 browser->selection->map); 2039 browser->selection ?
1972 2040 browser->selection->map : NULL);
2041 nr_options += add_socket_opt(browser, &actions[nr_options],
2042 &options[nr_options],
2043 socked_id);
1973 /* perf script support */ 2044 /* perf script support */
1974 if (browser->he_selection) { 2045 if (browser->he_selection) {
1975 nr_options += add_script_opt(browser, 2046 nr_options += add_script_opt(browser,
1976 &actions[nr_options], 2047 &actions[nr_options],
1977 &options[nr_options], 2048 &options[nr_options],
1978 thread, NULL); 2049 thread, NULL);
2050 /*
2051 * Note that browser->selection != NULL
2052 * when browser->he_selection is not NULL,
2053 * so we don't need to check browser->selection
2054 * before fetching browser->selection->sym like what
2055 * we do before fetching browser->selection->map.
2056 *
2057 * See hist_browser__show_entry.
2058 */
1979 nr_options += add_script_opt(browser, 2059 nr_options += add_script_opt(browser,
1980 &actions[nr_options], 2060 &actions[nr_options],
1981 &options[nr_options], 2061 &options[nr_options],
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index 8c154c7d4669..80912778bb6d 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -72,7 +72,7 @@ static int map_browser__run(struct map_browser *browser)
72 int key; 72 int key;
73 73
74 if (ui_browser__show(&browser->b, browser->map->dso->long_name, 74 if (ui_browser__show(&browser->b, browser->map->dso->long_name,
75 "Press <- or ESC to exit, %s / to search", 75 "Press ESC to exit, %s / to search",
76 verbose ? "" : "restart with -v to use") < 0) 76 verbose ? "" : "restart with -v to use") < 0)
77 return -1; 77 return -1;
78 78
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index e13b48d705ef..ad6b6ee3770e 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -89,7 +89,7 @@ static int script_browser__run(struct perf_script_browser *browser)
89 int key; 89 int key;
90 90
91 if (ui_browser__show(&browser->b, browser->script_name, 91 if (ui_browser__show(&browser->b, browser->script_name,
92 "Press <- or ESC to exit") < 0) 92 "Press ESC to exit") < 0)
93 return -1; 93 return -1;
94 94
95 while (1) { 95 while (1) {
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 25d608394d74..5029ba2b55af 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -463,27 +463,27 @@ void perf_hpp__init(void)
463 return; 463 return;
464 464
465 if (symbol_conf.cumulate_callchain) { 465 if (symbol_conf.cumulate_callchain) {
466 perf_hpp__column_enable(PERF_HPP__OVERHEAD_ACC); 466 hpp_dimension__add_output(PERF_HPP__OVERHEAD_ACC);
467 perf_hpp__format[PERF_HPP__OVERHEAD].name = "Self"; 467 perf_hpp__format[PERF_HPP__OVERHEAD].name = "Self";
468 } 468 }
469 469
470 perf_hpp__column_enable(PERF_HPP__OVERHEAD); 470 hpp_dimension__add_output(PERF_HPP__OVERHEAD);
471 471
472 if (symbol_conf.show_cpu_utilization) { 472 if (symbol_conf.show_cpu_utilization) {
473 perf_hpp__column_enable(PERF_HPP__OVERHEAD_SYS); 473 hpp_dimension__add_output(PERF_HPP__OVERHEAD_SYS);
474 perf_hpp__column_enable(PERF_HPP__OVERHEAD_US); 474 hpp_dimension__add_output(PERF_HPP__OVERHEAD_US);
475 475
476 if (perf_guest) { 476 if (perf_guest) {
477 perf_hpp__column_enable(PERF_HPP__OVERHEAD_GUEST_SYS); 477 hpp_dimension__add_output(PERF_HPP__OVERHEAD_GUEST_SYS);
478 perf_hpp__column_enable(PERF_HPP__OVERHEAD_GUEST_US); 478 hpp_dimension__add_output(PERF_HPP__OVERHEAD_GUEST_US);
479 } 479 }
480 } 480 }
481 481
482 if (symbol_conf.show_nr_samples) 482 if (symbol_conf.show_nr_samples)
483 perf_hpp__column_enable(PERF_HPP__SAMPLES); 483 hpp_dimension__add_output(PERF_HPP__SAMPLES);
484 484
485 if (symbol_conf.show_total_period) 485 if (symbol_conf.show_total_period)
486 perf_hpp__column_enable(PERF_HPP__PERIOD); 486 hpp_dimension__add_output(PERF_HPP__PERIOD);
487 487
488 /* prepend overhead field for backward compatiblity. */ 488 /* prepend overhead field for backward compatiblity. */
489 list = &perf_hpp__format[PERF_HPP__OVERHEAD].sort_list; 489 list = &perf_hpp__format[PERF_HPP__OVERHEAD].sort_list;
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index 60d1f29b4b50..7dfeba0a91f3 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -141,10 +141,6 @@ int ui__init(void)
141 141
142 SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB); 142 SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB);
143 143
144 ui_helpline__init();
145 ui_browser__init();
146 tui_progress__init();
147
148 signal(SIGSEGV, ui__signal_backtrace); 144 signal(SIGSEGV, ui__signal_backtrace);
149 signal(SIGFPE, ui__signal_backtrace); 145 signal(SIGFPE, ui__signal_backtrace);
150 signal(SIGINT, ui__signal); 146 signal(SIGINT, ui__signal);
@@ -153,6 +149,10 @@ int ui__init(void)
153 149
154 perf_error__register(&perf_tui_eops); 150 perf_error__register(&perf_tui_eops);
155 151
152 ui_helpline__init();
153 ui_browser__init();
154 tui_progress__init();
155
156 hist_browser__init_hpp(); 156 hist_browser__init_hpp();
157out: 157out:
158 return err; 158 return err;
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 349bc96ca1fe..591b3fe3ed49 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -5,6 +5,7 @@ libperf-y += build-id.o
5libperf-y += config.o 5libperf-y += config.o
6libperf-y += ctype.o 6libperf-y += ctype.o
7libperf-y += db-export.o 7libperf-y += db-export.o
8libperf-y += env.o
8libperf-y += environment.o 9libperf-y += environment.o
9libperf-y += event.o 10libperf-y += event.o
10libperf-y += evlist.o 11libperf-y += evlist.o
@@ -17,6 +18,7 @@ libperf-y += levenshtein.o
17libperf-y += llvm-utils.o 18libperf-y += llvm-utils.o
18libperf-y += parse-options.o 19libperf-y += parse-options.o
19libperf-y += parse-events.o 20libperf-y += parse-events.o
21libperf-y += perf_regs.o
20libperf-y += path.o 22libperf-y += path.o
21libperf-y += rbtree.o 23libperf-y += rbtree.o
22libperf-y += bitmap.o 24libperf-y += bitmap.o
@@ -85,6 +87,7 @@ libperf-$(CONFIG_AUXTRACE) += intel-bts.o
85libperf-y += parse-branch-options.o 87libperf-y += parse-branch-options.o
86libperf-y += parse-regs-options.o 88libperf-y += parse-regs-options.o
87 89
90libperf-$(CONFIG_LIBBPF) += bpf-loader.o
88libperf-$(CONFIG_LIBELF) += symbol-elf.o 91libperf-$(CONFIG_LIBELF) += symbol-elf.o
89libperf-$(CONFIG_LIBELF) += probe-file.o 92libperf-$(CONFIG_LIBELF) += probe-file.o
90libperf-$(CONFIG_LIBELF) += probe-event.o 93libperf-$(CONFIG_LIBELF) += probe-event.o
@@ -103,7 +106,6 @@ libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
103 106
104libperf-y += scripting-engines/ 107libperf-y += scripting-engines/
105 108
106libperf-$(CONFIG_PERF_REGS) += perf_regs.o
107libperf-$(CONFIG_ZLIB) += zlib.o 109libperf-$(CONFIG_ZLIB) += zlib.o
108libperf-$(CONFIG_LZMA) += lzma.o 110libperf-$(CONFIG_LZMA) += lzma.o
109 111
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index d1eece70b84d..0fc8d7a2fea5 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -548,8 +548,11 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
548 548
549 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 549 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
550 550
551 if (addr < sym->start || addr >= sym->end) 551 if (addr < sym->start || addr >= sym->end) {
552 pr_debug("%s(%d): ERANGE! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 "\n",
553 __func__, __LINE__, sym->name, sym->start, addr, sym->end);
552 return -ERANGE; 554 return -ERANGE;
555 }
553 556
554 offset = addr - sym->start; 557 offset = addr - sym->start;
555 h = annotation__histogram(notes, evidx); 558 h = annotation__histogram(notes, evidx);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index e9996092a093..cea323d9ee7e 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -122,7 +122,7 @@ struct annotated_source {
122 struct list_head source; 122 struct list_head source;
123 struct source_line *lines; 123 struct source_line *lines;
124 int nr_histograms; 124 int nr_histograms;
125 int sizeof_sym_hist; 125 size_t sizeof_sym_hist;
126 struct cyc_hist *cycles_hist; 126 struct cyc_hist *cycles_hist;
127 struct sym_hist histograms[0]; 127 struct sym_hist histograms[0];
128}; 128};
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index a980e7c50ee0..7f10430af39c 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -926,6 +926,8 @@ s64 perf_event__process_auxtrace(struct perf_tool *tool,
926#define PERF_ITRACE_DEFAULT_PERIOD 100000 926#define PERF_ITRACE_DEFAULT_PERIOD 100000
927#define PERF_ITRACE_DEFAULT_CALLCHAIN_SZ 16 927#define PERF_ITRACE_DEFAULT_CALLCHAIN_SZ 16
928#define PERF_ITRACE_MAX_CALLCHAIN_SZ 1024 928#define PERF_ITRACE_MAX_CALLCHAIN_SZ 1024
929#define PERF_ITRACE_DEFAULT_LAST_BRANCH_SZ 64
930#define PERF_ITRACE_MAX_LAST_BRANCH_SZ 1024
929 931
930void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts) 932void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts)
931{ 933{
@@ -936,6 +938,7 @@ void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts)
936 synth_opts->period_type = PERF_ITRACE_DEFAULT_PERIOD_TYPE; 938 synth_opts->period_type = PERF_ITRACE_DEFAULT_PERIOD_TYPE;
937 synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD; 939 synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD;
938 synth_opts->callchain_sz = PERF_ITRACE_DEFAULT_CALLCHAIN_SZ; 940 synth_opts->callchain_sz = PERF_ITRACE_DEFAULT_CALLCHAIN_SZ;
941 synth_opts->last_branch_sz = PERF_ITRACE_DEFAULT_LAST_BRANCH_SZ;
939} 942}
940 943
941/* 944/*
@@ -950,6 +953,7 @@ int itrace_parse_synth_opts(const struct option *opt, const char *str,
950 const char *p; 953 const char *p;
951 char *endptr; 954 char *endptr;
952 bool period_type_set = false; 955 bool period_type_set = false;
956 bool period_set = false;
953 957
954 synth_opts->set = true; 958 synth_opts->set = true;
955 959
@@ -971,6 +975,7 @@ int itrace_parse_synth_opts(const struct option *opt, const char *str,
971 p += 1; 975 p += 1;
972 if (isdigit(*p)) { 976 if (isdigit(*p)) {
973 synth_opts->period = strtoull(p, &endptr, 10); 977 synth_opts->period = strtoull(p, &endptr, 10);
978 period_set = true;
974 p = endptr; 979 p = endptr;
975 while (*p == ' ' || *p == ',') 980 while (*p == ' ' || *p == ',')
976 p += 1; 981 p += 1;
@@ -1041,6 +1046,23 @@ int itrace_parse_synth_opts(const struct option *opt, const char *str,
1041 synth_opts->callchain_sz = val; 1046 synth_opts->callchain_sz = val;
1042 } 1047 }
1043 break; 1048 break;
1049 case 'l':
1050 synth_opts->last_branch = true;
1051 synth_opts->last_branch_sz =
1052 PERF_ITRACE_DEFAULT_LAST_BRANCH_SZ;
1053 while (*p == ' ' || *p == ',')
1054 p += 1;
1055 if (isdigit(*p)) {
1056 unsigned int val;
1057
1058 val = strtoul(p, &endptr, 10);
1059 p = endptr;
1060 if (!val ||
1061 val > PERF_ITRACE_MAX_LAST_BRANCH_SZ)
1062 goto out_err;
1063 synth_opts->last_branch_sz = val;
1064 }
1065 break;
1044 case ' ': 1066 case ' ':
1045 case ',': 1067 case ',':
1046 break; 1068 break;
@@ -1053,7 +1075,7 @@ out:
1053 if (!period_type_set) 1075 if (!period_type_set)
1054 synth_opts->period_type = 1076 synth_opts->period_type =
1055 PERF_ITRACE_DEFAULT_PERIOD_TYPE; 1077 PERF_ITRACE_DEFAULT_PERIOD_TYPE;
1056 if (!synth_opts->period) 1078 if (!period_set)
1057 synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD; 1079 synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD;
1058 } 1080 }
1059 1081
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index bf72b77a588a..b86f90db1352 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -63,7 +63,9 @@ 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 * @last_branch: add branch context to 'instruction' events
66 * @callchain_sz: maximum callchain size 67 * @callchain_sz: maximum callchain size
68 * @last_branch_sz: branch context size
67 * @period: 'instructions' events period 69 * @period: 'instructions' events period
68 * @period_type: 'instructions' events period type 70 * @period_type: 'instructions' events period type
69 */ 71 */
@@ -79,7 +81,9 @@ struct itrace_synth_opts {
79 bool calls; 81 bool calls;
80 bool returns; 82 bool returns;
81 bool callchain; 83 bool callchain;
84 bool last_branch;
82 unsigned int callchain_sz; 85 unsigned int callchain_sz;
86 unsigned int last_branch_sz;
83 unsigned long long period; 87 unsigned long long period;
84 enum itrace_period_type period_type; 88 enum itrace_period_type period_type;
85}; 89};
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
new file mode 100644
index 000000000000..ba6f7526b282
--- /dev/null
+++ b/tools/perf/util/bpf-loader.c
@@ -0,0 +1,352 @@
1/*
2 * bpf-loader.c
3 *
4 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
5 * Copyright (C) 2015 Huawei Inc.
6 */
7
8#include <bpf/libbpf.h>
9#include <linux/err.h>
10#include "perf.h"
11#include "debug.h"
12#include "bpf-loader.h"
13#include "probe-event.h"
14#include "probe-finder.h" // for MAX_PROBES
15#include "llvm-utils.h"
16
17#define DEFINE_PRINT_FN(name, level) \
18static int libbpf_##name(const char *fmt, ...) \
19{ \
20 va_list args; \
21 int ret; \
22 \
23 va_start(args, fmt); \
24 ret = veprintf(level, verbose, pr_fmt(fmt), args);\
25 va_end(args); \
26 return ret; \
27}
28
29DEFINE_PRINT_FN(warning, 0)
30DEFINE_PRINT_FN(info, 0)
31DEFINE_PRINT_FN(debug, 1)
32
33struct bpf_prog_priv {
34 struct perf_probe_event pev;
35};
36
37struct bpf_object *bpf__prepare_load(const char *filename, bool source)
38{
39 struct bpf_object *obj;
40 static bool libbpf_initialized;
41
42 if (!libbpf_initialized) {
43 libbpf_set_print(libbpf_warning,
44 libbpf_info,
45 libbpf_debug);
46 libbpf_initialized = true;
47 }
48
49 if (source) {
50 int err;
51 void *obj_buf;
52 size_t obj_buf_sz;
53
54 err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz);
55 if (err)
56 return ERR_PTR(err);
57 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename);
58 free(obj_buf);
59 } else
60 obj = bpf_object__open(filename);
61
62 if (!obj) {
63 pr_debug("bpf: failed to load %s\n", filename);
64 return ERR_PTR(-EINVAL);
65 }
66
67 return obj;
68}
69
70void bpf__clear(void)
71{
72 struct bpf_object *obj, *tmp;
73
74 bpf_object__for_each_safe(obj, tmp) {
75 bpf__unprobe(obj);
76 bpf_object__close(obj);
77 }
78}
79
80static void
81bpf_prog_priv__clear(struct bpf_program *prog __maybe_unused,
82 void *_priv)
83{
84 struct bpf_prog_priv *priv = _priv;
85
86 cleanup_perf_probe_events(&priv->pev, 1);
87 free(priv);
88}
89
90static int
91config_bpf_program(struct bpf_program *prog)
92{
93 struct perf_probe_event *pev = NULL;
94 struct bpf_prog_priv *priv = NULL;
95 const char *config_str;
96 int err;
97
98 config_str = bpf_program__title(prog, false);
99 if (!config_str) {
100 pr_debug("bpf: unable to get title for program\n");
101 return -EINVAL;
102 }
103
104 priv = calloc(sizeof(*priv), 1);
105 if (!priv) {
106 pr_debug("bpf: failed to alloc priv\n");
107 return -ENOMEM;
108 }
109 pev = &priv->pev;
110
111 pr_debug("bpf: config program '%s'\n", config_str);
112 err = parse_perf_probe_command(config_str, pev);
113 if (err < 0) {
114 pr_debug("bpf: '%s' is not a valid config string\n",
115 config_str);
116 err = -EINVAL;
117 goto errout;
118 }
119
120 if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
121 pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
122 config_str, PERF_BPF_PROBE_GROUP);
123 err = -EINVAL;
124 goto errout;
125 } else if (!pev->group)
126 pev->group = strdup(PERF_BPF_PROBE_GROUP);
127
128 if (!pev->group) {
129 pr_debug("bpf: strdup failed\n");
130 err = -ENOMEM;
131 goto errout;
132 }
133
134 if (!pev->event) {
135 pr_debug("bpf: '%s': event name is missing\n",
136 config_str);
137 err = -EINVAL;
138 goto errout;
139 }
140 pr_debug("bpf: config '%s' is ok\n", config_str);
141
142 err = bpf_program__set_private(prog, priv, bpf_prog_priv__clear);
143 if (err) {
144 pr_debug("Failed to set priv for program '%s'\n", config_str);
145 goto errout;
146 }
147
148 return 0;
149
150errout:
151 if (pev)
152 clear_perf_probe_event(pev);
153 free(priv);
154 return err;
155}
156
157static int bpf__prepare_probe(void)
158{
159 static int err = 0;
160 static bool initialized = false;
161
162 /*
163 * Make err static, so if init failed the first, bpf__prepare_probe()
164 * fails each time without calling init_probe_symbol_maps multiple
165 * times.
166 */
167 if (initialized)
168 return err;
169
170 initialized = true;
171 err = init_probe_symbol_maps(false);
172 if (err < 0)
173 pr_debug("Failed to init_probe_symbol_maps\n");
174 probe_conf.max_probes = MAX_PROBES;
175 return err;
176}
177
178int bpf__probe(struct bpf_object *obj)
179{
180 int err = 0;
181 struct bpf_program *prog;
182 struct bpf_prog_priv *priv;
183 struct perf_probe_event *pev;
184
185 err = bpf__prepare_probe();
186 if (err) {
187 pr_debug("bpf__prepare_probe failed\n");
188 return err;
189 }
190
191 bpf_object__for_each_program(prog, obj) {
192 err = config_bpf_program(prog);
193 if (err)
194 goto out;
195
196 err = bpf_program__get_private(prog, (void **)&priv);
197 if (err || !priv)
198 goto out;
199 pev = &priv->pev;
200
201 err = convert_perf_probe_events(pev, 1);
202 if (err < 0) {
203 pr_debug("bpf_probe: failed to convert perf probe events");
204 goto out;
205 }
206
207 err = apply_perf_probe_events(pev, 1);
208 if (err < 0) {
209 pr_debug("bpf_probe: failed to apply perf probe events");
210 goto out;
211 }
212 }
213out:
214 return err < 0 ? err : 0;
215}
216
217#define EVENTS_WRITE_BUFSIZE 4096
218int bpf__unprobe(struct bpf_object *obj)
219{
220 int err, ret = 0;
221 struct bpf_program *prog;
222 struct bpf_prog_priv *priv;
223
224 bpf_object__for_each_program(prog, obj) {
225 int i;
226
227 err = bpf_program__get_private(prog, (void **)&priv);
228 if (err || !priv)
229 continue;
230
231 for (i = 0; i < priv->pev.ntevs; i++) {
232 struct probe_trace_event *tev = &priv->pev.tevs[i];
233 char name_buf[EVENTS_WRITE_BUFSIZE];
234 struct strfilter *delfilter;
235
236 snprintf(name_buf, EVENTS_WRITE_BUFSIZE,
237 "%s:%s", tev->group, tev->event);
238 name_buf[EVENTS_WRITE_BUFSIZE - 1] = '\0';
239
240 delfilter = strfilter__new(name_buf, NULL);
241 if (!delfilter) {
242 pr_debug("Failed to create filter for unprobing\n");
243 ret = -ENOMEM;
244 continue;
245 }
246
247 err = del_perf_probe_events(delfilter);
248 strfilter__delete(delfilter);
249 if (err) {
250 pr_debug("Failed to delete %s\n", name_buf);
251 ret = err;
252 continue;
253 }
254 }
255 }
256 return ret;
257}
258
259int bpf__load(struct bpf_object *obj)
260{
261 int err;
262
263 err = bpf_object__load(obj);
264 if (err) {
265 pr_debug("bpf: load objects failed\n");
266 return err;
267 }
268 return 0;
269}
270
271int bpf__foreach_tev(struct bpf_object *obj,
272 bpf_prog_iter_callback_t func,
273 void *arg)
274{
275 struct bpf_program *prog;
276 int err;
277
278 bpf_object__for_each_program(prog, obj) {
279 struct probe_trace_event *tev;
280 struct perf_probe_event *pev;
281 struct bpf_prog_priv *priv;
282 int i, fd;
283
284 err = bpf_program__get_private(prog,
285 (void **)&priv);
286 if (err || !priv) {
287 pr_debug("bpf: failed to get private field\n");
288 return -EINVAL;
289 }
290
291 pev = &priv->pev;
292 for (i = 0; i < pev->ntevs; i++) {
293 tev = &pev->tevs[i];
294
295 fd = bpf_program__fd(prog);
296 if (fd < 0) {
297 pr_debug("bpf: failed to get file descriptor\n");
298 return fd;
299 }
300
301 err = (*func)(tev, fd, arg);
302 if (err) {
303 pr_debug("bpf: call back failed, stop iterate\n");
304 return err;
305 }
306 }
307 }
308 return 0;
309}
310
311#define bpf__strerror_head(err, buf, size) \
312 char sbuf[STRERR_BUFSIZE], *emsg;\
313 if (!size)\
314 return 0;\
315 if (err < 0)\
316 err = -err;\
317 emsg = strerror_r(err, sbuf, sizeof(sbuf));\
318 switch (err) {\
319 default:\
320 scnprintf(buf, size, "%s", emsg);\
321 break;
322
323#define bpf__strerror_entry(val, fmt...)\
324 case val: {\
325 scnprintf(buf, size, fmt);\
326 break;\
327 }
328
329#define bpf__strerror_end(buf, size)\
330 }\
331 buf[size - 1] = '\0';
332
333int bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
334 int err, char *buf, size_t size)
335{
336 bpf__strerror_head(err, buf, size);
337 bpf__strerror_entry(EEXIST, "Probe point exist. Try use 'perf probe -d \"*\"'");
338 bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0\n");
339 bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file\n");
340 bpf__strerror_end(buf, size);
341 return 0;
342}
343
344int bpf__strerror_load(struct bpf_object *obj __maybe_unused,
345 int err, char *buf, size_t size)
346{
347 bpf__strerror_head(err, buf, size);
348 bpf__strerror_entry(EINVAL, "%s: Are you root and runing a CONFIG_BPF_SYSCALL kernel?",
349 emsg)
350 bpf__strerror_end(buf, size);
351 return 0;
352}
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
new file mode 100644
index 000000000000..ccd8d7fd79d3
--- /dev/null
+++ b/tools/perf/util/bpf-loader.h
@@ -0,0 +1,85 @@
1/*
2 * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com>
3 * Copyright (C) 2015, Huawei Inc.
4 */
5#ifndef __BPF_LOADER_H
6#define __BPF_LOADER_H
7
8#include <linux/compiler.h>
9#include <linux/err.h>
10#include <string.h>
11#include "probe-event.h"
12#include "debug.h"
13
14struct bpf_object;
15#define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
16
17typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev,
18 int fd, void *arg);
19
20#ifdef HAVE_LIBBPF_SUPPORT
21struct bpf_object *bpf__prepare_load(const char *filename, bool source);
22
23void bpf__clear(void);
24
25int bpf__probe(struct bpf_object *obj);
26int bpf__unprobe(struct bpf_object *obj);
27int bpf__strerror_probe(struct bpf_object *obj, int err,
28 char *buf, size_t size);
29
30int bpf__load(struct bpf_object *obj);
31int bpf__strerror_load(struct bpf_object *obj, int err,
32 char *buf, size_t size);
33int bpf__foreach_tev(struct bpf_object *obj,
34 bpf_prog_iter_callback_t func, void *arg);
35#else
36static inline struct bpf_object *
37bpf__prepare_load(const char *filename __maybe_unused,
38 bool source __maybe_unused)
39{
40 pr_debug("ERROR: eBPF object loading is disabled during compiling.\n");
41 return ERR_PTR(-ENOTSUP);
42}
43
44static inline void bpf__clear(void) { }
45
46static inline int bpf__probe(struct bpf_object *obj __maybe_unused) { return 0;}
47static inline int bpf__unprobe(struct bpf_object *obj __maybe_unused) { return 0;}
48static inline int bpf__load(struct bpf_object *obj __maybe_unused) { return 0; }
49
50static inline int
51bpf__foreach_tev(struct bpf_object *obj __maybe_unused,
52 bpf_prog_iter_callback_t func __maybe_unused,
53 void *arg __maybe_unused)
54{
55 return 0;
56}
57
58static inline int
59__bpf_strerror(char *buf, size_t size)
60{
61 if (!size)
62 return 0;
63 strncpy(buf,
64 "ERROR: eBPF object loading is disabled during compiling.\n",
65 size);
66 buf[size - 1] = '\0';
67 return 0;
68}
69
70static inline int
71bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
72 int err __maybe_unused,
73 char *buf, size_t size)
74{
75 return __bpf_strerror(buf, size);
76}
77
78static inline int bpf__strerror_load(struct bpf_object *obj __maybe_unused,
79 int err __maybe_unused,
80 char *buf, size_t size)
81{
82 return __bpf_strerror(buf, size);
83}
84#endif
85#endif
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 773fe13ce627..735ad48e1858 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -51,10 +51,12 @@ static int parse_callchain_order(const char *value)
51{ 51{
52 if (!strncmp(value, "caller", strlen(value))) { 52 if (!strncmp(value, "caller", strlen(value))) {
53 callchain_param.order = ORDER_CALLER; 53 callchain_param.order = ORDER_CALLER;
54 callchain_param.order_set = true;
54 return 0; 55 return 0;
55 } 56 }
56 if (!strncmp(value, "callee", strlen(value))) { 57 if (!strncmp(value, "callee", strlen(value))) {
57 callchain_param.order = ORDER_CALLEE; 58 callchain_param.order = ORDER_CALLEE;
59 callchain_param.order_set = true;
58 return 0; 60 return 0;
59 } 61 }
60 return -1; 62 return -1;
@@ -77,12 +79,14 @@ static int parse_callchain_sort_key(const char *value)
77 return -1; 79 return -1;
78} 80}
79 81
80int 82static int
81parse_callchain_report_opt(const char *arg) 83__parse_callchain_report_opt(const char *arg, bool allow_record_opt)
82{ 84{
83 char *tok; 85 char *tok;
84 char *endptr; 86 char *endptr;
85 bool minpcnt_set = false; 87 bool minpcnt_set = false;
88 bool record_opt_set = false;
89 bool try_stack_size = false;
86 90
87 symbol_conf.use_callchain = true; 91 symbol_conf.use_callchain = true;
88 92
@@ -100,6 +104,28 @@ parse_callchain_report_opt(const char *arg)
100 !parse_callchain_order(tok) || 104 !parse_callchain_order(tok) ||
101 !parse_callchain_sort_key(tok)) { 105 !parse_callchain_sort_key(tok)) {
102 /* parsing ok - move on to the next */ 106 /* parsing ok - move on to the next */
107 try_stack_size = false;
108 goto next;
109 } else if (allow_record_opt && !record_opt_set) {
110 if (parse_callchain_record(tok, &callchain_param))
111 goto try_numbers;
112
113 /* assume that number followed by 'dwarf' is stack size */
114 if (callchain_param.record_mode == CALLCHAIN_DWARF)
115 try_stack_size = true;
116
117 record_opt_set = true;
118 goto next;
119 }
120
121try_numbers:
122 if (try_stack_size) {
123 unsigned long size = 0;
124
125 if (get_stack_size(tok, &size) < 0)
126 return -1;
127 callchain_param.dump_size = size;
128 try_stack_size = false;
103 } else if (!minpcnt_set) { 129 } else if (!minpcnt_set) {
104 /* try to get the min percent */ 130 /* try to get the min percent */
105 callchain_param.min_percent = strtod(tok, &endptr); 131 callchain_param.min_percent = strtod(tok, &endptr);
@@ -112,7 +138,7 @@ parse_callchain_report_opt(const char *arg)
112 if (tok == endptr) 138 if (tok == endptr)
113 return -1; 139 return -1;
114 } 140 }
115 141next:
116 arg = NULL; 142 arg = NULL;
117 } 143 }
118 144
@@ -123,6 +149,16 @@ parse_callchain_report_opt(const char *arg)
123 return 0; 149 return 0;
124} 150}
125 151
152int parse_callchain_report_opt(const char *arg)
153{
154 return __parse_callchain_report_opt(arg, false);
155}
156
157int parse_callchain_top_opt(const char *arg)
158{
159 return __parse_callchain_report_opt(arg, true);
160}
161
126int perf_callchain_config(const char *var, const char *value) 162int perf_callchain_config(const char *var, const char *value)
127{ 163{
128 char *endptr; 164 char *endptr;
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index acee2b3cd801..fce8161e54db 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -7,6 +7,30 @@
7#include "event.h" 7#include "event.h"
8#include "symbol.h" 8#include "symbol.h"
9 9
10#define HELP_PAD "\t\t\t\t"
11
12#define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace):\n\n"
13
14#ifdef HAVE_DWARF_UNWIND_SUPPORT
15# define RECORD_MODE_HELP HELP_PAD "record_mode:\tcall graph recording mode (fp|dwarf|lbr)\n"
16#else
17# define RECORD_MODE_HELP HELP_PAD "record_mode:\tcall graph recording mode (fp|lbr)\n"
18#endif
19
20#define RECORD_SIZE_HELP \
21 HELP_PAD "record_size:\tif record_mode is 'dwarf', max size of stack recording (<bytes>)\n" \
22 HELP_PAD "\t\tdefault: 8192 (bytes)\n"
23
24#define CALLCHAIN_RECORD_HELP CALLCHAIN_HELP RECORD_MODE_HELP RECORD_SIZE_HELP
25
26#define CALLCHAIN_REPORT_HELP \
27 HELP_PAD "print_type:\tcall graph printing style (graph|flat|fractal|none)\n" \
28 HELP_PAD "threshold:\tminimum call graph inclusion threshold (<percent>)\n" \
29 HELP_PAD "print_limit:\tmaximum number of call graph entry (<number>)\n" \
30 HELP_PAD "order:\t\tcall graph order (caller|callee)\n" \
31 HELP_PAD "sort_key:\tcall graph sort key (function|address)\n" \
32 HELP_PAD "branch:\t\tinclude last branch info to call graph (branch)\n"
33
10enum perf_call_graph_mode { 34enum perf_call_graph_mode {
11 CALLCHAIN_NONE, 35 CALLCHAIN_NONE,
12 CALLCHAIN_FP, 36 CALLCHAIN_FP,
@@ -63,6 +87,7 @@ struct callchain_param {
63 double min_percent; 87 double min_percent;
64 sort_chain_func_t sort; 88 sort_chain_func_t sort;
65 enum chain_order order; 89 enum chain_order order;
90 bool order_set;
66 enum chain_key key; 91 enum chain_key key;
67 bool branch_callstack; 92 bool branch_callstack;
68}; 93};
@@ -180,6 +205,7 @@ extern const char record_callchain_help[];
180extern int parse_callchain_record(const char *arg, struct callchain_param *param); 205extern int parse_callchain_record(const char *arg, struct callchain_param *param);
181int parse_callchain_record_opt(const char *arg, struct callchain_param *param); 206int parse_callchain_record_opt(const char *arg, struct callchain_param *param);
182int parse_callchain_report_opt(const char *arg); 207int parse_callchain_report_opt(const char *arg);
208int parse_callchain_top_opt(const char *arg);
183int perf_callchain_config(const char *var, const char *value); 209int perf_callchain_config(const char *var, const char *value);
184 210
185static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, 211static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 3667e2123e5b..10af1e7524fb 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -203,6 +203,23 @@ struct cpu_map *cpu_map__dummy_new(void)
203 return cpus; 203 return cpus;
204} 204}
205 205
206struct cpu_map *cpu_map__empty_new(int nr)
207{
208 struct cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int) * nr);
209
210 if (cpus != NULL) {
211 int i;
212
213 cpus->nr = nr;
214 for (i = 0; i < nr; i++)
215 cpus->map[i] = -1;
216
217 atomic_set(&cpus->refcnt, 1);
218 }
219
220 return cpus;
221}
222
206static void cpu_map__delete(struct cpu_map *map) 223static void cpu_map__delete(struct cpu_map *map)
207{ 224{
208 if (map) { 225 if (map) {
@@ -225,32 +242,32 @@ void cpu_map__put(struct cpu_map *map)
225 cpu_map__delete(map); 242 cpu_map__delete(map);
226} 243}
227 244
228int cpu_map__get_socket(struct cpu_map *map, int idx) 245static int cpu__get_topology_int(int cpu, const char *name, int *value)
229{ 246{
230 FILE *fp;
231 const char *mnt;
232 char path[PATH_MAX]; 247 char path[PATH_MAX];
233 int cpu, ret;
234 248
235 if (idx > map->nr) 249 snprintf(path, PATH_MAX,
236 return -1; 250 "devices/system/cpu/cpu%d/topology/%s", cpu, name);
237 251
238 cpu = map->map[idx]; 252 return sysfs__read_int(path, value);
253}
239 254
240 mnt = sysfs__mountpoint(); 255int cpu_map__get_socket_id(int cpu)
241 if (!mnt) 256{
242 return -1; 257 int value, ret = cpu__get_topology_int(cpu, "physical_package_id", &value);
258 return ret ?: value;
259}
243 260
244 snprintf(path, PATH_MAX, 261int cpu_map__get_socket(struct cpu_map *map, int idx, void *data __maybe_unused)
245 "%s/devices/system/cpu/cpu%d/topology/physical_package_id", 262{
246 mnt, cpu); 263 int cpu;
247 264
248 fp = fopen(path, "r"); 265 if (idx > map->nr)
249 if (!fp)
250 return -1; 266 return -1;
251 ret = fscanf(fp, "%d", &cpu); 267
252 fclose(fp); 268 cpu = map->map[idx];
253 return ret == 1 ? cpu : -1; 269
270 return cpu_map__get_socket_id(cpu);
254} 271}
255 272
256static int cmp_ids(const void *a, const void *b) 273static int cmp_ids(const void *a, const void *b)
@@ -258,8 +275,9 @@ static int cmp_ids(const void *a, const void *b)
258 return *(int *)a - *(int *)b; 275 return *(int *)a - *(int *)b;
259} 276}
260 277
261static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, 278int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
262 int (*f)(struct cpu_map *map, int cpu)) 279 int (*f)(struct cpu_map *map, int cpu, void *data),
280 void *data)
263{ 281{
264 struct cpu_map *c; 282 struct cpu_map *c;
265 int nr = cpus->nr; 283 int nr = cpus->nr;
@@ -271,7 +289,7 @@ static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
271 return -1; 289 return -1;
272 290
273 for (cpu = 0; cpu < nr; cpu++) { 291 for (cpu = 0; cpu < nr; cpu++) {
274 s1 = f(cpus, cpu); 292 s1 = f(cpus, cpu, data);
275 for (s2 = 0; s2 < c->nr; s2++) { 293 for (s2 = 0; s2 < c->nr; s2++) {
276 if (s1 == c->map[s2]) 294 if (s1 == c->map[s2])
277 break; 295 break;
@@ -284,40 +302,29 @@ static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
284 /* ensure we process id in increasing order */ 302 /* ensure we process id in increasing order */
285 qsort(c->map, c->nr, sizeof(int), cmp_ids); 303 qsort(c->map, c->nr, sizeof(int), cmp_ids);
286 304
287 atomic_set(&cpus->refcnt, 1); 305 atomic_set(&c->refcnt, 1);
288 *res = c; 306 *res = c;
289 return 0; 307 return 0;
290} 308}
291 309
292int cpu_map__get_core(struct cpu_map *map, int idx) 310int cpu_map__get_core_id(int cpu)
293{ 311{
294 FILE *fp; 312 int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
295 const char *mnt; 313 return ret ?: value;
296 char path[PATH_MAX]; 314}
297 int cpu, ret, s; 315
316int cpu_map__get_core(struct cpu_map *map, int idx, void *data)
317{
318 int cpu, s;
298 319
299 if (idx > map->nr) 320 if (idx > map->nr)
300 return -1; 321 return -1;
301 322
302 cpu = map->map[idx]; 323 cpu = map->map[idx];
303 324
304 mnt = sysfs__mountpoint(); 325 cpu = cpu_map__get_core_id(cpu);
305 if (!mnt)
306 return -1;
307
308 snprintf(path, PATH_MAX,
309 "%s/devices/system/cpu/cpu%d/topology/core_id",
310 mnt, cpu);
311
312 fp = fopen(path, "r");
313 if (!fp)
314 return -1;
315 ret = fscanf(fp, "%d", &cpu);
316 fclose(fp);
317 if (ret != 1)
318 return -1;
319 326
320 s = cpu_map__get_socket(map, idx); 327 s = cpu_map__get_socket(map, idx, data);
321 if (s == -1) 328 if (s == -1)
322 return -1; 329 return -1;
323 330
@@ -332,12 +339,12 @@ int cpu_map__get_core(struct cpu_map *map, int idx)
332 339
333int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) 340int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp)
334{ 341{
335 return cpu_map__build_map(cpus, sockp, cpu_map__get_socket); 342 return cpu_map__build_map(cpus, sockp, cpu_map__get_socket, NULL);
336} 343}
337 344
338int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep) 345int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep)
339{ 346{
340 return cpu_map__build_map(cpus, corep, cpu_map__get_core); 347 return cpu_map__build_map(cpus, corep, cpu_map__get_core, NULL);
341} 348}
342 349
343/* setup simple routines to easily access node numbers given a cpu number */ 350/* setup simple routines to easily access node numbers given a cpu number */
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 0af9cecb4c51..85f7772457fa 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -15,11 +15,14 @@ struct cpu_map {
15}; 15};
16 16
17struct cpu_map *cpu_map__new(const char *cpu_list); 17struct cpu_map *cpu_map__new(const char *cpu_list);
18struct cpu_map *cpu_map__empty_new(int nr);
18struct cpu_map *cpu_map__dummy_new(void); 19struct cpu_map *cpu_map__dummy_new(void);
19struct cpu_map *cpu_map__read(FILE *file); 20struct cpu_map *cpu_map__read(FILE *file);
20size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp); 21size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
21int cpu_map__get_socket(struct cpu_map *map, int idx); 22int cpu_map__get_socket_id(int cpu);
22int cpu_map__get_core(struct cpu_map *map, int idx); 23int cpu_map__get_socket(struct cpu_map *map, int idx, void *data);
24int cpu_map__get_core_id(int cpu);
25int cpu_map__get_core(struct cpu_map *map, int idx, void *data);
23int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp); 26int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp);
24int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep); 27int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep);
25 28
@@ -85,4 +88,7 @@ static inline int cpu__get_node(int cpu)
85 return cpunode_map[cpu]; 88 return cpunode_map[cpu];
86} 89}
87 90
91int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
92 int (*f)(struct cpu_map *map, int cpu, void *data),
93 void *data);
88#endif /* __PERF_CPUMAP_H */ 94#endif /* __PERF_CPUMAP_H */
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
new file mode 100644
index 000000000000..6af4f7c36820
--- /dev/null
+++ b/tools/perf/util/env.c
@@ -0,0 +1,86 @@
1#include "cpumap.h"
2#include "env.h"
3#include "util.h"
4
5struct perf_env perf_env;
6
7void perf_env__exit(struct perf_env *env)
8{
9 zfree(&env->hostname);
10 zfree(&env->os_release);
11 zfree(&env->version);
12 zfree(&env->arch);
13 zfree(&env->cpu_desc);
14 zfree(&env->cpuid);
15 zfree(&env->cmdline);
16 zfree(&env->cmdline_argv);
17 zfree(&env->sibling_cores);
18 zfree(&env->sibling_threads);
19 zfree(&env->numa_nodes);
20 zfree(&env->pmu_mappings);
21 zfree(&env->cpu);
22}
23
24int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
25{
26 int i;
27
28 /*
29 * If env->cmdline_argv has already been set, do not override it. This allows
30 * a command to set the cmdline, parse args and then call another
31 * builtin function that implements a command -- e.g, cmd_kvm calling
32 * cmd_record.
33 */
34 if (env->cmdline_argv != NULL)
35 return 0;
36
37 /* do not include NULL termination */
38 env->cmdline_argv = calloc(argc, sizeof(char *));
39 if (env->cmdline_argv == NULL)
40 goto out_enomem;
41
42 /*
43 * Must copy argv contents because it gets moved around during option
44 * parsing:
45 */
46 for (i = 0; i < argc ; i++) {
47 env->cmdline_argv[i] = argv[i];
48 if (env->cmdline_argv[i] == NULL)
49 goto out_free;
50 }
51
52 env->nr_cmdline = argc;
53
54 return 0;
55out_free:
56 zfree(&env->cmdline_argv);
57out_enomem:
58 return -ENOMEM;
59}
60
61int perf_env__read_cpu_topology_map(struct perf_env *env)
62{
63 int cpu, nr_cpus;
64
65 if (env->cpu != NULL)
66 return 0;
67
68 if (env->nr_cpus_avail == 0)
69 env->nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF);
70
71 nr_cpus = env->nr_cpus_avail;
72 if (nr_cpus == -1)
73 return -EINVAL;
74
75 env->cpu = calloc(nr_cpus, sizeof(env->cpu[0]));
76 if (env->cpu == NULL)
77 return -ENOMEM;
78
79 for (cpu = 0; cpu < nr_cpus; ++cpu) {
80 env->cpu[cpu].core_id = cpu_map__get_core_id(cpu);
81 env->cpu[cpu].socket_id = cpu_map__get_socket_id(cpu);
82 }
83
84 env->nr_cpus_avail = nr_cpus;
85 return 0;
86}
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
new file mode 100644
index 000000000000..0132b9557c02
--- /dev/null
+++ b/tools/perf/util/env.h
@@ -0,0 +1,44 @@
1#ifndef __PERF_ENV_H
2#define __PERF_ENV_H
3
4struct cpu_topology_map {
5 int socket_id;
6 int core_id;
7};
8
9struct perf_env {
10 char *hostname;
11 char *os_release;
12 char *version;
13 char *arch;
14 int nr_cpus_online;
15 int nr_cpus_avail;
16 char *cpu_desc;
17 char *cpuid;
18 unsigned long long total_mem;
19 unsigned int msr_pmu_type;
20
21 int nr_cmdline;
22 int nr_sibling_cores;
23 int nr_sibling_threads;
24 int nr_numa_nodes;
25 int nr_pmu_mappings;
26 int nr_groups;
27 char *cmdline;
28 const char **cmdline_argv;
29 char *sibling_cores;
30 char *sibling_threads;
31 char *numa_nodes;
32 char *pmu_mappings;
33 struct cpu_topology_map *cpu;
34};
35
36extern struct perf_env perf_env;
37
38void perf_env__exit(struct perf_env *env);
39
40int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]);
41
42int perf_env__read_cpu_topology_map(struct perf_env *env);
43
44#endif /* __PERF_ENV_H */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 7ff61274ed57..8b10621b415c 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -67,7 +67,8 @@ static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len,
67 char filename[PATH_MAX]; 67 char filename[PATH_MAX];
68 char bf[4096]; 68 char bf[4096];
69 int fd; 69 int fd;
70 size_t size = 0, n; 70 size_t size = 0;
71 ssize_t n;
71 char *nl, *name, *tgids, *ppids; 72 char *nl, *name, *tgids, *ppids;
72 73
73 *tgid = -1; 74 *tgid = -1;
@@ -167,7 +168,7 @@ static int perf_event__prepare_comm(union perf_event *event, pid_t pid,
167 return 0; 168 return 0;
168} 169}
169 170
170static pid_t perf_event__synthesize_comm(struct perf_tool *tool, 171pid_t perf_event__synthesize_comm(struct perf_tool *tool,
171 union perf_event *event, pid_t pid, 172 union perf_event *event, pid_t pid,
172 perf_event__handler_t process, 173 perf_event__handler_t process,
173 struct machine *machine) 174 struct machine *machine)
@@ -378,7 +379,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool,
378 for (pos = maps__first(maps); pos; pos = map__next(pos)) { 379 for (pos = maps__first(maps); pos; pos = map__next(pos)) {
379 size_t size; 380 size_t size;
380 381
381 if (pos->dso->kernel) 382 if (__map__is_kernel(pos))
382 continue; 383 continue;
383 384
384 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); 385 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
@@ -649,12 +650,12 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
649 size_t size; 650 size_t size;
650 const char *mmap_name; 651 const char *mmap_name;
651 char name_buff[PATH_MAX]; 652 char name_buff[PATH_MAX];
652 struct map *map; 653 struct map *map = machine__kernel_map(machine);
653 struct kmap *kmap; 654 struct kmap *kmap;
654 int err; 655 int err;
655 union perf_event *event; 656 union perf_event *event;
656 657
657 if (machine->vmlinux_maps[0] == NULL) 658 if (map == NULL)
658 return -1; 659 return -1;
659 660
660 /* 661 /*
@@ -680,7 +681,6 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
680 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; 681 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
681 } 682 }
682 683
683 map = machine->vmlinux_maps[MAP__FUNCTION];
684 kmap = map__kmap(map); 684 kmap = map__kmap(map);
685 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), 685 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
686 "%s%s", mmap_name, kmap->ref_reloc_sym->name) + 1; 686 "%s%s", mmap_name, kmap->ref_reloc_sym->name) + 1;
@@ -1008,7 +1008,7 @@ int perf_event__preprocess_sample(const union perf_event *event,
1008 * it now. 1008 * it now.
1009 */ 1009 */
1010 if (cpumode == PERF_RECORD_MISC_KERNEL && 1010 if (cpumode == PERF_RECORD_MISC_KERNEL &&
1011 machine->vmlinux_maps[MAP__FUNCTION] == NULL) 1011 machine__kernel_map(machine) == NULL)
1012 machine__create_kernel_maps(machine); 1012 machine__create_kernel_maps(machine);
1013 1013
1014 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, al); 1014 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, al);
@@ -1021,6 +1021,14 @@ int perf_event__preprocess_sample(const union perf_event *event,
1021 1021
1022 al->sym = NULL; 1022 al->sym = NULL;
1023 al->cpu = sample->cpu; 1023 al->cpu = sample->cpu;
1024 al->socket = -1;
1025
1026 if (al->cpu >= 0) {
1027 struct perf_env *env = machine->env;
1028
1029 if (env && env->cpu)
1030 al->socket = env->cpu[al->cpu].socket_id;
1031 }
1024 1032
1025 if (al->map) { 1033 if (al->map) {
1026 struct dso *dso = al->map->dso; 1034 struct dso *dso = al->map->dso;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index f729df5e25e6..a0dbcbd4f6d8 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -257,6 +257,7 @@ struct events_stats {
257 u64 total_non_filtered_period; 257 u64 total_non_filtered_period;
258 u64 total_lost; 258 u64 total_lost;
259 u64 total_lost_samples; 259 u64 total_lost_samples;
260 u64 total_aux_lost;
260 u64 total_invalid_chains; 261 u64 total_invalid_chains;
261 u32 nr_events[PERF_RECORD_HEADER_MAX]; 262 u32 nr_events[PERF_RECORD_HEADER_MAX];
262 u32 nr_non_filtered_samples; 263 u32 nr_non_filtered_samples;
@@ -478,6 +479,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
478 const struct perf_sample *sample, 479 const struct perf_sample *sample,
479 bool swapped); 480 bool swapped);
480 481
482pid_t perf_event__synthesize_comm(struct perf_tool *tool,
483 union perf_event *event, pid_t pid,
484 perf_event__handler_t process,
485 struct machine *machine);
486
481int perf_event__synthesize_mmap_events(struct perf_tool *tool, 487int perf_event__synthesize_mmap_events(struct perf_tool *tool,
482 union perf_event *event, 488 union perf_event *event,
483 pid_t pid, pid_t tgid, 489 pid_t pid, pid_t tgid,
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index d51a5200c8af..d1392194a9a9 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -25,6 +25,7 @@
25#include <linux/bitops.h> 25#include <linux/bitops.h>
26#include <linux/hash.h> 26#include <linux/hash.h>
27#include <linux/log2.h> 27#include <linux/log2.h>
28#include <linux/err.h>
28 29
29static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); 30static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx);
30static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); 31static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx);
@@ -124,6 +125,33 @@ void perf_evlist__delete(struct perf_evlist *evlist)
124 free(evlist); 125 free(evlist);
125} 126}
126 127
128static void __perf_evlist__propagate_maps(struct perf_evlist *evlist,
129 struct perf_evsel *evsel)
130{
131 /*
132 * We already have cpus for evsel (via PMU sysfs) so
133 * keep it, if there's no target cpu list defined.
134 */
135 if (!evsel->own_cpus || evlist->has_user_cpus) {
136 cpu_map__put(evsel->cpus);
137 evsel->cpus = cpu_map__get(evlist->cpus);
138 } else if (evsel->cpus != evsel->own_cpus) {
139 cpu_map__put(evsel->cpus);
140 evsel->cpus = cpu_map__get(evsel->own_cpus);
141 }
142
143 thread_map__put(evsel->threads);
144 evsel->threads = thread_map__get(evlist->threads);
145}
146
147static void perf_evlist__propagate_maps(struct perf_evlist *evlist)
148{
149 struct perf_evsel *evsel;
150
151 evlist__for_each(evlist, evsel)
152 __perf_evlist__propagate_maps(evlist, evsel);
153}
154
127void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) 155void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
128{ 156{
129 entry->evlist = evlist; 157 entry->evlist = evlist;
@@ -133,18 +161,26 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
133 161
134 if (!evlist->nr_entries++) 162 if (!evlist->nr_entries++)
135 perf_evlist__set_id_pos(evlist); 163 perf_evlist__set_id_pos(evlist);
164
165 __perf_evlist__propagate_maps(evlist, entry);
166}
167
168void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel)
169{
170 evsel->evlist = NULL;
171 list_del_init(&evsel->node);
172 evlist->nr_entries -= 1;
136} 173}
137 174
138void perf_evlist__splice_list_tail(struct perf_evlist *evlist, 175void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
139 struct list_head *list, 176 struct list_head *list)
140 int nr_entries)
141{ 177{
142 bool set_id_pos = !evlist->nr_entries; 178 struct perf_evsel *evsel, *temp;
143 179
144 list_splice_tail(list, &evlist->entries); 180 __evlist__for_each_safe(list, temp, evsel) {
145 evlist->nr_entries += nr_entries; 181 list_del_init(&evsel->node);
146 if (set_id_pos) 182 perf_evlist__add(evlist, evsel);
147 perf_evlist__set_id_pos(evlist); 183 }
148} 184}
149 185
150void __perf_evlist__set_leader(struct list_head *list) 186void __perf_evlist__set_leader(struct list_head *list)
@@ -169,6 +205,20 @@ void perf_evlist__set_leader(struct perf_evlist *evlist)
169 } 205 }
170} 206}
171 207
208void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr)
209{
210 attr->precise_ip = 3;
211
212 while (attr->precise_ip != 0) {
213 int fd = sys_perf_event_open(attr, 0, -1, -1, 0);
214 if (fd != -1) {
215 close(fd);
216 break;
217 }
218 --attr->precise_ip;
219 }
220}
221
172int perf_evlist__add_default(struct perf_evlist *evlist) 222int perf_evlist__add_default(struct perf_evlist *evlist)
173{ 223{
174 struct perf_event_attr attr = { 224 struct perf_event_attr attr = {
@@ -179,13 +229,15 @@ int perf_evlist__add_default(struct perf_evlist *evlist)
179 229
180 event_attr_init(&attr); 230 event_attr_init(&attr);
181 231
232 perf_event_attr__set_max_precise_ip(&attr);
233
182 evsel = perf_evsel__new(&attr); 234 evsel = perf_evsel__new(&attr);
183 if (evsel == NULL) 235 if (evsel == NULL)
184 goto error; 236 goto error;
185 237
186 /* use strdup() because free(evsel) assumes name is allocated */ 238 /* use asprintf() because free(evsel) assumes name is allocated */
187 evsel->name = strdup("cycles"); 239 if (asprintf(&evsel->name, "cycles%.*s",
188 if (!evsel->name) 240 attr.precise_ip ? attr.precise_ip + 1 : 0, ":ppp") < 0)
189 goto error_free; 241 goto error_free;
190 242
191 perf_evlist__add(evlist, evsel); 243 perf_evlist__add(evlist, evsel);
@@ -210,7 +262,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
210 list_add_tail(&evsel->node, &head); 262 list_add_tail(&evsel->node, &head);
211 } 263 }
212 264
213 perf_evlist__splice_list_tail(evlist, &head, nr_attrs); 265 perf_evlist__splice_list_tail(evlist, &head);
214 266
215 return 0; 267 return 0;
216 268
@@ -265,7 +317,7 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,
265{ 317{
266 struct perf_evsel *evsel = perf_evsel__newtp(sys, name); 318 struct perf_evsel *evsel = perf_evsel__newtp(sys, name);
267 319
268 if (evsel == NULL) 320 if (IS_ERR(evsel))
269 return -1; 321 return -1;
270 322
271 evsel->handler = handler; 323 evsel->handler = handler;
@@ -588,6 +640,21 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
588 return NULL; 640 return NULL;
589} 641}
590 642
643struct perf_evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist,
644 u64 id)
645{
646 struct perf_sample_id *sid;
647
648 if (!id)
649 return NULL;
650
651 sid = perf_evlist__id2sid(evlist, id);
652 if (sid)
653 return sid->evsel;
654
655 return NULL;
656}
657
591static int perf_evlist__event2id(struct perf_evlist *evlist, 658static int perf_evlist__event2id(struct perf_evlist *evlist,
592 union perf_event *event, u64 *id) 659 union perf_event *event, u64 *id)
593{ 660{
@@ -1103,71 +1170,56 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
1103 return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false); 1170 return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false);
1104} 1171}
1105 1172
1106static int perf_evlist__propagate_maps(struct perf_evlist *evlist,
1107 bool has_user_cpus)
1108{
1109 struct perf_evsel *evsel;
1110
1111 evlist__for_each(evlist, evsel) {
1112 /*
1113 * We already have cpus for evsel (via PMU sysfs) so
1114 * keep it, if there's no target cpu list defined.
1115 */
1116 if (evsel->cpus && has_user_cpus)
1117 cpu_map__put(evsel->cpus);
1118
1119 if (!evsel->cpus || has_user_cpus)
1120 evsel->cpus = cpu_map__get(evlist->cpus);
1121
1122 evsel->threads = thread_map__get(evlist->threads);
1123
1124 if ((evlist->cpus && !evsel->cpus) ||
1125 (evlist->threads && !evsel->threads))
1126 return -ENOMEM;
1127 }
1128
1129 return 0;
1130}
1131
1132int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) 1173int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
1133{ 1174{
1134 evlist->threads = thread_map__new_str(target->pid, target->tid, 1175 struct cpu_map *cpus;
1135 target->uid); 1176 struct thread_map *threads;
1177
1178 threads = thread_map__new_str(target->pid, target->tid, target->uid);
1136 1179
1137 if (evlist->threads == NULL) 1180 if (!threads)
1138 return -1; 1181 return -1;
1139 1182
1140 if (target__uses_dummy_map(target)) 1183 if (target__uses_dummy_map(target))
1141 evlist->cpus = cpu_map__dummy_new(); 1184 cpus = cpu_map__dummy_new();
1142 else 1185 else
1143 evlist->cpus = cpu_map__new(target->cpu_list); 1186 cpus = cpu_map__new(target->cpu_list);
1144 1187
1145 if (evlist->cpus == NULL) 1188 if (!cpus)
1146 goto out_delete_threads; 1189 goto out_delete_threads;
1147 1190
1148 return perf_evlist__propagate_maps(evlist, !!target->cpu_list); 1191 evlist->has_user_cpus = !!target->cpu_list;
1192
1193 perf_evlist__set_maps(evlist, cpus, threads);
1194
1195 return 0;
1149 1196
1150out_delete_threads: 1197out_delete_threads:
1151 thread_map__put(evlist->threads); 1198 thread_map__put(threads);
1152 evlist->threads = NULL;
1153 return -1; 1199 return -1;
1154} 1200}
1155 1201
1156int perf_evlist__set_maps(struct perf_evlist *evlist, 1202void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus,
1157 struct cpu_map *cpus, 1203 struct thread_map *threads)
1158 struct thread_map *threads)
1159{ 1204{
1160 if (evlist->cpus) 1205 /*
1206 * Allow for the possibility that one or another of the maps isn't being
1207 * changed i.e. don't put it. Note we are assuming the maps that are
1208 * being applied are brand new and evlist is taking ownership of the
1209 * original reference count of 1. If that is not the case it is up to
1210 * the caller to increase the reference count.
1211 */
1212 if (cpus != evlist->cpus) {
1161 cpu_map__put(evlist->cpus); 1213 cpu_map__put(evlist->cpus);
1214 evlist->cpus = cpus;
1215 }
1162 1216
1163 evlist->cpus = cpus; 1217 if (threads != evlist->threads) {
1164
1165 if (evlist->threads)
1166 thread_map__put(evlist->threads); 1218 thread_map__put(evlist->threads);
1219 evlist->threads = threads;
1220 }
1167 1221
1168 evlist->threads = threads; 1222 perf_evlist__propagate_maps(evlist);
1169
1170 return perf_evlist__propagate_maps(evlist, false);
1171} 1223}
1172 1224
1173int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel) 1225int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel)
@@ -1387,6 +1439,8 @@ void perf_evlist__close(struct perf_evlist *evlist)
1387 1439
1388static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) 1440static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
1389{ 1441{
1442 struct cpu_map *cpus;
1443 struct thread_map *threads;
1390 int err = -ENOMEM; 1444 int err = -ENOMEM;
1391 1445
1392 /* 1446 /*
@@ -1398,20 +1452,19 @@ static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
1398 * error, and we may not want to do that fallback to a 1452 * error, and we may not want to do that fallback to a
1399 * default cpu identity map :-\ 1453 * default cpu identity map :-\
1400 */ 1454 */
1401 evlist->cpus = cpu_map__new(NULL); 1455 cpus = cpu_map__new(NULL);
1402 if (evlist->cpus == NULL) 1456 if (!cpus)
1403 goto out; 1457 goto out;
1404 1458
1405 evlist->threads = thread_map__new_dummy(); 1459 threads = thread_map__new_dummy();
1406 if (evlist->threads == NULL) 1460 if (!threads)
1407 goto out_free_cpus; 1461 goto out_put;
1408 1462
1409 err = 0; 1463 perf_evlist__set_maps(evlist, cpus, threads);
1410out: 1464out:
1411 return err; 1465 return err;
1412out_free_cpus: 1466out_put:
1413 cpu_map__put(evlist->cpus); 1467 cpu_map__put(cpus);
1414 evlist->cpus = NULL;
1415 goto out; 1468 goto out;
1416} 1469}
1417 1470
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index b39a6198f4ac..a459fe71b452 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -42,6 +42,7 @@ struct perf_evlist {
42 int nr_mmaps; 42 int nr_mmaps;
43 bool overwrite; 43 bool overwrite;
44 bool enabled; 44 bool enabled;
45 bool has_user_cpus;
45 size_t mmap_len; 46 size_t mmap_len;
46 int id_pos; 47 int id_pos;
47 int is_pos; 48 int is_pos;
@@ -72,6 +73,7 @@ void perf_evlist__exit(struct perf_evlist *evlist);
72void perf_evlist__delete(struct perf_evlist *evlist); 73void perf_evlist__delete(struct perf_evlist *evlist);
73 74
74void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); 75void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry);
76void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel);
75int perf_evlist__add_default(struct perf_evlist *evlist); 77int perf_evlist__add_default(struct perf_evlist *evlist);
76int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, 78int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
77 struct perf_event_attr *attrs, size_t nr_attrs); 79 struct perf_event_attr *attrs, size_t nr_attrs);
@@ -103,6 +105,8 @@ int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mas
103int perf_evlist__poll(struct perf_evlist *evlist, int timeout); 105int perf_evlist__poll(struct perf_evlist *evlist, int timeout);
104 106
105struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); 107struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
108struct perf_evsel *perf_evlist__id2evsel_strict(struct perf_evlist *evlist,
109 u64 id);
106 110
107struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id); 111struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
108 112
@@ -155,9 +159,8 @@ int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
155void perf_evlist__set_selected(struct perf_evlist *evlist, 159void perf_evlist__set_selected(struct perf_evlist *evlist,
156 struct perf_evsel *evsel); 160 struct perf_evsel *evsel);
157 161
158int perf_evlist__set_maps(struct perf_evlist *evlist, 162void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus,
159 struct cpu_map *cpus, 163 struct thread_map *threads);
160 struct thread_map *threads);
161int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); 164int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target);
162int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); 165int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel);
163 166
@@ -179,8 +182,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist);
179bool perf_evlist__valid_read_format(struct perf_evlist *evlist); 182bool perf_evlist__valid_read_format(struct perf_evlist *evlist);
180 183
181void perf_evlist__splice_list_tail(struct perf_evlist *evlist, 184void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
182 struct list_head *list, 185 struct list_head *list);
183 int nr_entries);
184 186
185static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) 187static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist)
186{ 188{
@@ -288,4 +290,6 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
288 290
289void perf_evlist__set_tracking_event(struct perf_evlist *evlist, 291void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
290 struct perf_evsel *tracking_evsel); 292 struct perf_evsel *tracking_evsel);
293
294void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr);
291#endif /* __PERF_EVLIST_H */ 295#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index c53f79123b37..397fb4ed3c97 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -9,10 +9,11 @@
9 9
10#include <byteswap.h> 10#include <byteswap.h>
11#include <linux/bitops.h> 11#include <linux/bitops.h>
12#include <api/fs/debugfs.h> 12#include <api/fs/tracing_path.h>
13#include <traceevent/event-parse.h> 13#include <traceevent/event-parse.h>
14#include <linux/hw_breakpoint.h> 14#include <linux/hw_breakpoint.h>
15#include <linux/perf_event.h> 15#include <linux/perf_event.h>
16#include <linux/err.h>
16#include <sys/resource.h> 17#include <sys/resource.h>
17#include "asm/bug.h" 18#include "asm/bug.h"
18#include "callchain.h" 19#include "callchain.h"
@@ -207,6 +208,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
207 evsel->unit = ""; 208 evsel->unit = "";
208 evsel->scale = 1.0; 209 evsel->scale = 1.0;
209 evsel->evlist = NULL; 210 evsel->evlist = NULL;
211 evsel->bpf_fd = -1;
210 INIT_LIST_HEAD(&evsel->node); 212 INIT_LIST_HEAD(&evsel->node);
211 INIT_LIST_HEAD(&evsel->config_terms); 213 INIT_LIST_HEAD(&evsel->config_terms);
212 perf_evsel__object.init(evsel); 214 perf_evsel__object.init(evsel);
@@ -225,11 +227,17 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
225 return evsel; 227 return evsel;
226} 228}
227 229
230/*
231 * Returns pointer with encoded error via <linux/err.h> interface.
232 */
228struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) 233struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx)
229{ 234{
230 struct perf_evsel *evsel = zalloc(perf_evsel__object.size); 235 struct perf_evsel *evsel = zalloc(perf_evsel__object.size);
236 int err = -ENOMEM;
231 237
232 if (evsel != NULL) { 238 if (evsel == NULL) {
239 goto out_err;
240 } else {
233 struct perf_event_attr attr = { 241 struct perf_event_attr attr = {
234 .type = PERF_TYPE_TRACEPOINT, 242 .type = PERF_TYPE_TRACEPOINT,
235 .sample_type = (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | 243 .sample_type = (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
@@ -240,8 +248,10 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int
240 goto out_free; 248 goto out_free;
241 249
242 evsel->tp_format = trace_event__tp_format(sys, name); 250 evsel->tp_format = trace_event__tp_format(sys, name);
243 if (evsel->tp_format == NULL) 251 if (IS_ERR(evsel->tp_format)) {
252 err = PTR_ERR(evsel->tp_format);
244 goto out_free; 253 goto out_free;
254 }
245 255
246 event_attr_init(&attr); 256 event_attr_init(&attr);
247 attr.config = evsel->tp_format->id; 257 attr.config = evsel->tp_format->id;
@@ -254,7 +264,8 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int
254out_free: 264out_free:
255 zfree(&evsel->name); 265 zfree(&evsel->name);
256 free(evsel); 266 free(evsel);
257 return NULL; 267out_err:
268 return ERR_PTR(err);
258} 269}
259 270
260const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { 271const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {
@@ -642,6 +653,15 @@ static void apply_config_terms(struct perf_evsel *evsel,
642 case PERF_EVSEL__CONFIG_TERM_STACK_USER: 653 case PERF_EVSEL__CONFIG_TERM_STACK_USER:
643 dump_size = term->val.stack_user; 654 dump_size = term->val.stack_user;
644 break; 655 break;
656 case PERF_EVSEL__CONFIG_TERM_INHERIT:
657 /*
658 * attr->inherit should has already been set by
659 * perf_evsel__config. If user explicitly set
660 * inherit using config terms, override global
661 * opt->no_inherit setting.
662 */
663 attr->inherit = term->val.inherit ? 1 : 0;
664 break;
645 default: 665 default:
646 break; 666 break;
647 } 667 }
@@ -872,6 +892,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
872 attr->clockid = opts->clockid; 892 attr->clockid = opts->clockid;
873 } 893 }
874 894
895 if (evsel->precise_max)
896 perf_event_attr__set_max_precise_ip(attr);
897
875 /* 898 /*
876 * Apply event specific term settings, 899 * Apply event specific term settings,
877 * it overloads any global configuration. 900 * it overloads any global configuration.
@@ -1033,6 +1056,7 @@ void perf_evsel__exit(struct perf_evsel *evsel)
1033 perf_evsel__free_config_terms(evsel); 1056 perf_evsel__free_config_terms(evsel);
1034 close_cgroup(evsel->cgrp); 1057 close_cgroup(evsel->cgrp);
1035 cpu_map__put(evsel->cpus); 1058 cpu_map__put(evsel->cpus);
1059 cpu_map__put(evsel->own_cpus);
1036 thread_map__put(evsel->threads); 1060 thread_map__put(evsel->threads);
1037 zfree(&evsel->group_name); 1061 zfree(&evsel->group_name);
1038 zfree(&evsel->name); 1062 zfree(&evsel->name);
@@ -1167,7 +1191,7 @@ static void __p_sample_type(char *buf, size_t size, u64 value)
1167 bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU), 1191 bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU),
1168 bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), 1192 bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW),
1169 bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), 1193 bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER),
1170 bit_name(IDENTIFIER), bit_name(REGS_INTR), 1194 bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC),
1171 { .name = NULL, } 1195 { .name = NULL, }
1172 }; 1196 };
1173#undef bit_name 1197#undef bit_name
@@ -1248,6 +1272,7 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr,
1248 PRINT_ATTRf(bp_type, p_unsigned); 1272 PRINT_ATTRf(bp_type, p_unsigned);
1249 PRINT_ATTRn("{ bp_addr, config1 }", bp_addr, p_hex); 1273 PRINT_ATTRn("{ bp_addr, config1 }", bp_addr, p_hex);
1250 PRINT_ATTRn("{ bp_len, config2 }", bp_len, p_hex); 1274 PRINT_ATTRn("{ bp_len, config2 }", bp_len, p_hex);
1275 PRINT_ATTRf(branch_sample_type, p_unsigned);
1251 PRINT_ATTRf(sample_regs_user, p_hex); 1276 PRINT_ATTRf(sample_regs_user, p_hex);
1252 PRINT_ATTRf(sample_stack_user, p_unsigned); 1277 PRINT_ATTRf(sample_stack_user, p_unsigned);
1253 PRINT_ATTRf(clockid, p_signed); 1278 PRINT_ATTRf(clockid, p_signed);
@@ -1332,6 +1357,22 @@ retry_open:
1332 err); 1357 err);
1333 goto try_fallback; 1358 goto try_fallback;
1334 } 1359 }
1360
1361 if (evsel->bpf_fd >= 0) {
1362 int evt_fd = FD(evsel, cpu, thread);
1363 int bpf_fd = evsel->bpf_fd;
1364
1365 err = ioctl(evt_fd,
1366 PERF_EVENT_IOC_SET_BPF,
1367 bpf_fd);
1368 if (err && errno != EEXIST) {
1369 pr_err("failed to attach bpf fd %d: %s\n",
1370 bpf_fd, strerror(errno));
1371 err = -EINVAL;
1372 goto out_close;
1373 }
1374 }
1375
1335 set_rlimit = NO_CHANGE; 1376 set_rlimit = NO_CHANGE;
1336 1377
1337 /* 1378 /*
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 298e6bbca200..0e49bd742c63 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -43,6 +43,7 @@ enum {
43 PERF_EVSEL__CONFIG_TERM_TIME, 43 PERF_EVSEL__CONFIG_TERM_TIME,
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_MAX, 47 PERF_EVSEL__CONFIG_TERM_MAX,
47}; 48};
48 49
@@ -55,6 +56,7 @@ struct perf_evsel_config_term {
55 bool time; 56 bool time;
56 char *callgraph; 57 char *callgraph;
57 u64 stack_user; 58 u64 stack_user;
59 bool inherit;
58 } val; 60 } val;
59}; 61};
60 62
@@ -90,14 +92,15 @@ struct perf_evsel {
90 double scale; 92 double scale;
91 const char *unit; 93 const char *unit;
92 struct event_format *tp_format; 94 struct event_format *tp_format;
95 off_t id_offset;
93 union { 96 union {
94 void *priv; 97 void *priv;
95 off_t id_offset;
96 u64 db_id; 98 u64 db_id;
97 }; 99 };
98 struct cgroup_sel *cgrp; 100 struct cgroup_sel *cgrp;
99 void *handler; 101 void *handler;
100 struct cpu_map *cpus; 102 struct cpu_map *cpus;
103 struct cpu_map *own_cpus;
101 struct thread_map *threads; 104 struct thread_map *threads;
102 unsigned int sample_size; 105 unsigned int sample_size;
103 int id_pos; 106 int id_pos;
@@ -110,6 +113,7 @@ struct perf_evsel {
110 bool system_wide; 113 bool system_wide;
111 bool tracking; 114 bool tracking;
112 bool per_pkg; 115 bool per_pkg;
116 bool precise_max;
113 /* parse modifier helper */ 117 /* parse modifier helper */
114 int exclude_GH; 118 int exclude_GH;
115 int nr_members; 119 int nr_members;
@@ -119,6 +123,7 @@ struct perf_evsel {
119 char *group_name; 123 char *group_name;
120 bool cmdline_group_boundary; 124 bool cmdline_group_boundary;
121 struct list_head config_terms; 125 struct list_head config_terms;
126 int bpf_fd;
122}; 127};
123 128
124union u64_swap { 129union u64_swap {
@@ -129,7 +134,6 @@ union u64_swap {
129struct cpu_map; 134struct cpu_map;
130struct target; 135struct target;
131struct thread_map; 136struct thread_map;
132struct perf_evlist;
133struct record_opts; 137struct record_opts;
134 138
135static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel) 139static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
@@ -161,6 +165,9 @@ static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr)
161 165
162struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx); 166struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx);
163 167
168/*
169 * Returns pointer with encoded error via <linux/err.h> interface.
170 */
164static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name) 171static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name)
165{ 172{
166 return perf_evsel__newtp_idx(sys, name, 0); 173 return perf_evsel__newtp_idx(sys, name, 0);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 41814547da15..43838003c1a1 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -24,9 +24,6 @@
24#include "build-id.h" 24#include "build-id.h"
25#include "data.h" 25#include "data.h"
26 26
27static u32 header_argc;
28static const char **header_argv;
29
30/* 27/*
31 * magic2 = "PERFILE2" 28 * magic2 = "PERFILE2"
32 * must be a numerical value to let the endianness 29 * must be a numerical value to let the endianness
@@ -88,6 +85,9 @@ int write_padded(int fd, const void *bf, size_t count, size_t count_aligned)
88 return err; 85 return err;
89} 86}
90 87
88#define string_size(str) \
89 (PERF_ALIGN((strlen(str) + 1), NAME_ALIGN) + sizeof(u32))
90
91static int do_write_string(int fd, const char *str) 91static int do_write_string(int fd, const char *str)
92{ 92{
93 u32 len, olen; 93 u32 len, olen;
@@ -135,37 +135,6 @@ static char *do_read_string(int fd, struct perf_header *ph)
135 return NULL; 135 return NULL;
136} 136}
137 137
138int
139perf_header__set_cmdline(int argc, const char **argv)
140{
141 int i;
142
143 /*
144 * If header_argv has already been set, do not override it.
145 * This allows a command to set the cmdline, parse args and
146 * then call another builtin function that implements a
147 * command -- e.g, cmd_kvm calling cmd_record.
148 */
149 if (header_argv)
150 return 0;
151
152 header_argc = (u32)argc;
153
154 /* do not include NULL termination */
155 header_argv = calloc(argc, sizeof(char *));
156 if (!header_argv)
157 return -ENOMEM;
158
159 /*
160 * must copy argv contents because it gets moved
161 * around during option parsing
162 */
163 for (i = 0; i < argc ; i++)
164 header_argv[i] = argv[i];
165
166 return 0;
167}
168
169static int write_tracing_data(int fd, struct perf_header *h __maybe_unused, 138static int write_tracing_data(int fd, struct perf_header *h __maybe_unused,
170 struct perf_evlist *evlist) 139 struct perf_evlist *evlist)
171{ 140{
@@ -402,8 +371,8 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused,
402{ 371{
403 char buf[MAXPATHLEN]; 372 char buf[MAXPATHLEN];
404 char proc[32]; 373 char proc[32];
405 u32 i, n; 374 u32 n;
406 int ret; 375 int i, ret;
407 376
408 /* 377 /*
409 * actual atual path to perf binary 378 * actual atual path to perf binary
@@ -417,7 +386,7 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused,
417 buf[ret] = '\0'; 386 buf[ret] = '\0';
418 387
419 /* account for binary path */ 388 /* account for binary path */
420 n = header_argc + 1; 389 n = perf_env.nr_cmdline + 1;
421 390
422 ret = do_write(fd, &n, sizeof(n)); 391 ret = do_write(fd, &n, sizeof(n));
423 if (ret < 0) 392 if (ret < 0)
@@ -427,8 +396,8 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused,
427 if (ret < 0) 396 if (ret < 0)
428 return ret; 397 return ret;
429 398
430 for (i = 0 ; i < header_argc; i++) { 399 for (i = 0 ; i < perf_env.nr_cmdline; i++) {
431 ret = do_write_string(fd, header_argv[i]); 400 ret = do_write_string(fd, perf_env.cmdline_argv[i]);
432 if (ret < 0) 401 if (ret < 0)
433 return ret; 402 return ret;
434 } 403 }
@@ -441,6 +410,7 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused,
441 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list" 410 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
442 411
443struct cpu_topo { 412struct cpu_topo {
413 u32 cpu_nr;
444 u32 core_sib; 414 u32 core_sib;
445 u32 thread_sib; 415 u32 thread_sib;
446 char **core_siblings; 416 char **core_siblings;
@@ -551,7 +521,7 @@ static struct cpu_topo *build_cpu_topology(void)
551 return NULL; 521 return NULL;
552 522
553 tp = addr; 523 tp = addr;
554 524 tp->cpu_nr = nr;
555 addr += sizeof(*tp); 525 addr += sizeof(*tp);
556 tp->core_siblings = addr; 526 tp->core_siblings = addr;
557 addr += sz; 527 addr += sz;
@@ -574,7 +544,7 @@ static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused,
574{ 544{
575 struct cpu_topo *tp; 545 struct cpu_topo *tp;
576 u32 i; 546 u32 i;
577 int ret; 547 int ret, j;
578 548
579 tp = build_cpu_topology(); 549 tp = build_cpu_topology();
580 if (!tp) 550 if (!tp)
@@ -598,6 +568,21 @@ static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused,
598 if (ret < 0) 568 if (ret < 0)
599 break; 569 break;
600 } 570 }
571
572 ret = perf_env__read_cpu_topology_map(&perf_env);
573 if (ret < 0)
574 goto done;
575
576 for (j = 0; j < perf_env.nr_cpus_avail; j++) {
577 ret = do_write(fd, &perf_env.cpu[j].core_id,
578 sizeof(perf_env.cpu[j].core_id));
579 if (ret < 0)
580 return ret;
581 ret = do_write(fd, &perf_env.cpu[j].socket_id,
582 sizeof(perf_env.cpu[j].socket_id));
583 if (ret < 0)
584 return ret;
585 }
601done: 586done:
602 free_cpu_topo(tp); 587 free_cpu_topo(tp);
603 return ret; 588 return ret;
@@ -938,6 +923,7 @@ static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
938{ 923{
939 int nr, i; 924 int nr, i;
940 char *str; 925 char *str;
926 int cpu_nr = ph->env.nr_cpus_online;
941 927
942 nr = ph->env.nr_sibling_cores; 928 nr = ph->env.nr_sibling_cores;
943 str = ph->env.sibling_cores; 929 str = ph->env.sibling_cores;
@@ -954,6 +940,13 @@ static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
954 fprintf(fp, "# sibling threads : %s\n", str); 940 fprintf(fp, "# sibling threads : %s\n", str);
955 str += strlen(str) + 1; 941 str += strlen(str) + 1;
956 } 942 }
943
944 if (ph->env.cpu != NULL) {
945 for (i = 0; i < cpu_nr; i++)
946 fprintf(fp, "# CPU %d: Core ID %d, Socket ID %d\n", i,
947 ph->env.cpu[i].core_id, ph->env.cpu[i].socket_id);
948 } else
949 fprintf(fp, "# Core ID and Socket ID information is not available\n");
957} 950}
958 951
959static void free_event_desc(struct perf_evsel *events) 952static void free_event_desc(struct perf_evsel *events)
@@ -1438,7 +1431,7 @@ static int process_nrcpus(struct perf_file_section *section __maybe_unused,
1438 if (ph->needs_swap) 1431 if (ph->needs_swap)
1439 nr = bswap_32(nr); 1432 nr = bswap_32(nr);
1440 1433
1441 ph->env.nr_cpus_online = nr; 1434 ph->env.nr_cpus_avail = nr;
1442 1435
1443 ret = readn(fd, &nr, sizeof(nr)); 1436 ret = readn(fd, &nr, sizeof(nr));
1444 if (ret != sizeof(nr)) 1437 if (ret != sizeof(nr))
@@ -1447,7 +1440,7 @@ static int process_nrcpus(struct perf_file_section *section __maybe_unused,
1447 if (ph->needs_swap) 1440 if (ph->needs_swap)
1448 nr = bswap_32(nr); 1441 nr = bswap_32(nr);
1449 1442
1450 ph->env.nr_cpus_avail = nr; 1443 ph->env.nr_cpus_online = nr;
1451 return 0; 1444 return 0;
1452} 1445}
1453 1446
@@ -1582,7 +1575,7 @@ error:
1582 return -1; 1575 return -1;
1583} 1576}
1584 1577
1585static int process_cpu_topology(struct perf_file_section *section __maybe_unused, 1578static int process_cpu_topology(struct perf_file_section *section,
1586 struct perf_header *ph, int fd, 1579 struct perf_header *ph, int fd,
1587 void *data __maybe_unused) 1580 void *data __maybe_unused)
1588{ 1581{
@@ -1590,15 +1583,22 @@ static int process_cpu_topology(struct perf_file_section *section __maybe_unused
1590 u32 nr, i; 1583 u32 nr, i;
1591 char *str; 1584 char *str;
1592 struct strbuf sb; 1585 struct strbuf sb;
1586 int cpu_nr = ph->env.nr_cpus_online;
1587 u64 size = 0;
1588
1589 ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu));
1590 if (!ph->env.cpu)
1591 return -1;
1593 1592
1594 ret = readn(fd, &nr, sizeof(nr)); 1593 ret = readn(fd, &nr, sizeof(nr));
1595 if (ret != sizeof(nr)) 1594 if (ret != sizeof(nr))
1596 return -1; 1595 goto free_cpu;
1597 1596
1598 if (ph->needs_swap) 1597 if (ph->needs_swap)
1599 nr = bswap_32(nr); 1598 nr = bswap_32(nr);
1600 1599
1601 ph->env.nr_sibling_cores = nr; 1600 ph->env.nr_sibling_cores = nr;
1601 size += sizeof(u32);
1602 strbuf_init(&sb, 128); 1602 strbuf_init(&sb, 128);
1603 1603
1604 for (i = 0; i < nr; i++) { 1604 for (i = 0; i < nr; i++) {
@@ -1608,6 +1608,7 @@ static int process_cpu_topology(struct perf_file_section *section __maybe_unused
1608 1608
1609 /* include a NULL character at the end */ 1609 /* include a NULL character at the end */
1610 strbuf_add(&sb, str, strlen(str) + 1); 1610 strbuf_add(&sb, str, strlen(str) + 1);
1611 size += string_size(str);
1611 free(str); 1612 free(str);
1612 } 1613 }
1613 ph->env.sibling_cores = strbuf_detach(&sb, NULL); 1614 ph->env.sibling_cores = strbuf_detach(&sb, NULL);
@@ -1620,6 +1621,7 @@ static int process_cpu_topology(struct perf_file_section *section __maybe_unused
1620 nr = bswap_32(nr); 1621 nr = bswap_32(nr);
1621 1622
1622 ph->env.nr_sibling_threads = nr; 1623 ph->env.nr_sibling_threads = nr;
1624 size += sizeof(u32);
1623 1625
1624 for (i = 0; i < nr; i++) { 1626 for (i = 0; i < nr; i++) {
1625 str = do_read_string(fd, ph); 1627 str = do_read_string(fd, ph);
@@ -1628,13 +1630,57 @@ static int process_cpu_topology(struct perf_file_section *section __maybe_unused
1628 1630
1629 /* include a NULL character at the end */ 1631 /* include a NULL character at the end */
1630 strbuf_add(&sb, str, strlen(str) + 1); 1632 strbuf_add(&sb, str, strlen(str) + 1);
1633 size += string_size(str);
1631 free(str); 1634 free(str);
1632 } 1635 }
1633 ph->env.sibling_threads = strbuf_detach(&sb, NULL); 1636 ph->env.sibling_threads = strbuf_detach(&sb, NULL);
1637
1638 /*
1639 * The header may be from old perf,
1640 * which doesn't include core id and socket id information.
1641 */
1642 if (section->size <= size) {
1643 zfree(&ph->env.cpu);
1644 return 0;
1645 }
1646
1647 for (i = 0; i < (u32)cpu_nr; i++) {
1648 ret = readn(fd, &nr, sizeof(nr));
1649 if (ret != sizeof(nr))
1650 goto free_cpu;
1651
1652 if (ph->needs_swap)
1653 nr = bswap_32(nr);
1654
1655 if (nr > (u32)cpu_nr) {
1656 pr_debug("core_id number is too big."
1657 "You may need to upgrade the perf tool.\n");
1658 goto free_cpu;
1659 }
1660 ph->env.cpu[i].core_id = nr;
1661
1662 ret = readn(fd, &nr, sizeof(nr));
1663 if (ret != sizeof(nr))
1664 goto free_cpu;
1665
1666 if (ph->needs_swap)
1667 nr = bswap_32(nr);
1668
1669 if (nr > (u32)cpu_nr) {
1670 pr_debug("socket_id number is too big."
1671 "You may need to upgrade the perf tool.\n");
1672 goto free_cpu;
1673 }
1674
1675 ph->env.cpu[i].socket_id = nr;
1676 }
1677
1634 return 0; 1678 return 0;
1635 1679
1636error: 1680error:
1637 strbuf_release(&sb); 1681 strbuf_release(&sb);
1682free_cpu:
1683 zfree(&ph->env.cpu);
1638 return -1; 1684 return -1;
1639} 1685}
1640 1686
@@ -1737,6 +1783,9 @@ static int process_pmu_mappings(struct perf_file_section *section __maybe_unused
1737 /* include a NULL character at the end */ 1783 /* include a NULL character at the end */
1738 strbuf_add(&sb, "", 1); 1784 strbuf_add(&sb, "", 1);
1739 1785
1786 if (!strcmp(name, "msr"))
1787 ph->env.msr_pmu_type = type;
1788
1740 free(name); 1789 free(name);
1741 pmu_num--; 1790 pmu_num--;
1742 } 1791 }
@@ -2515,6 +2564,7 @@ int perf_session__read_header(struct perf_session *session)
2515 return -ENOMEM; 2564 return -ENOMEM;
2516 2565
2517 session->evlist->env = &header->env; 2566 session->evlist->env = &header->env;
2567 session->machines.host.env = &header->env;
2518 if (perf_data_file__is_pipe(file)) 2568 if (perf_data_file__is_pipe(file))
2519 return perf_header__read_pipe(session); 2569 return perf_header__read_pipe(session);
2520 2570
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 396e4965f0c9..05f27cb6b7e3 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -7,7 +7,7 @@
7#include <linux/bitmap.h> 7#include <linux/bitmap.h>
8#include <linux/types.h> 8#include <linux/types.h>
9#include "event.h" 9#include "event.h"
10 10#include "env.h"
11 11
12enum { 12enum {
13 HEADER_RESERVED = 0, /* always cleared */ 13 HEADER_RESERVED = 0, /* always cleared */
@@ -66,31 +66,6 @@ struct perf_header;
66int perf_file_header__read(struct perf_file_header *header, 66int perf_file_header__read(struct perf_file_header *header,
67 struct perf_header *ph, int fd); 67 struct perf_header *ph, int fd);
68 68
69struct perf_env {
70 char *hostname;
71 char *os_release;
72 char *version;
73 char *arch;
74 int nr_cpus_online;
75 int nr_cpus_avail;
76 char *cpu_desc;
77 char *cpuid;
78 unsigned long long total_mem;
79
80 int nr_cmdline;
81 int nr_sibling_cores;
82 int nr_sibling_threads;
83 int nr_numa_nodes;
84 int nr_pmu_mappings;
85 int nr_groups;
86 char *cmdline;
87 const char **cmdline_argv;
88 char *sibling_cores;
89 char *sibling_threads;
90 char *numa_nodes;
91 char *pmu_mappings;
92};
93
94struct perf_header { 69struct perf_header {
95 enum perf_header_version version; 70 enum perf_header_version version;
96 bool needs_swap; 71 bool needs_swap;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 08b6cd945f1e..4fd37d6708cb 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -15,6 +15,8 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
15 struct hist_entry *he); 15 struct hist_entry *he);
16static bool hists__filter_entry_by_symbol(struct hists *hists, 16static bool hists__filter_entry_by_symbol(struct hists *hists,
17 struct hist_entry *he); 17 struct hist_entry *he);
18static bool hists__filter_entry_by_socket(struct hists *hists,
19 struct hist_entry *he);
18 20
19u16 hists__col_len(struct hists *hists, enum hist_column col) 21u16 hists__col_len(struct hists *hists, enum hist_column col)
20{ 22{
@@ -130,6 +132,18 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
130 hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, 132 hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
131 symlen); 133 symlen);
132 } 134 }
135
136 if (h->mem_info->iaddr.sym) {
137 symlen = (int)h->mem_info->iaddr.sym->namelen + 4
138 + unresolved_col_width + 2;
139 hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL,
140 symlen);
141 } else {
142 symlen = unresolved_col_width + 4 + 2;
143 hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL,
144 symlen);
145 }
146
133 if (h->mem_info->daddr.map) { 147 if (h->mem_info->daddr.map) {
134 symlen = dso__name_len(h->mem_info->daddr.map->dso); 148 symlen = dso__name_len(h->mem_info->daddr.map->dso);
135 hists__new_col_len(hists, HISTC_MEM_DADDR_DSO, 149 hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
@@ -141,9 +155,12 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
141 } else { 155 } else {
142 symlen = unresolved_col_width + 4 + 2; 156 symlen = unresolved_col_width + 4 + 2;
143 hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen); 157 hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen);
158 hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL, symlen);
144 hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO); 159 hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
145 } 160 }
146 161
162 hists__new_col_len(hists, HISTC_CPU, 3);
163 hists__new_col_len(hists, HISTC_SOCKET, 6);
147 hists__new_col_len(hists, HISTC_MEM_LOCKED, 6); 164 hists__new_col_len(hists, HISTC_MEM_LOCKED, 6);
148 hists__new_col_len(hists, HISTC_MEM_TLB, 22); 165 hists__new_col_len(hists, HISTC_MEM_TLB, 22);
149 hists__new_col_len(hists, HISTC_MEM_SNOOP, 12); 166 hists__new_col_len(hists, HISTC_MEM_SNOOP, 12);
@@ -452,6 +469,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
452 .map = al->map, 469 .map = al->map,
453 .sym = al->sym, 470 .sym = al->sym,
454 }, 471 },
472 .socket = al->socket,
455 .cpu = al->cpu, 473 .cpu = al->cpu,
456 .cpumode = al->cpumode, 474 .cpumode = al->cpumode,
457 .ip = al->addr, 475 .ip = al->addr,
@@ -690,7 +708,7 @@ iter_finish_normal_entry(struct hist_entry_iter *iter,
690} 708}
691 709
692static int 710static int
693iter_prepare_cumulative_entry(struct hist_entry_iter *iter __maybe_unused, 711iter_prepare_cumulative_entry(struct hist_entry_iter *iter,
694 struct addr_location *al __maybe_unused) 712 struct addr_location *al __maybe_unused)
695{ 713{
696 struct hist_entry **he_cache; 714 struct hist_entry **he_cache;
@@ -702,7 +720,7 @@ iter_prepare_cumulative_entry(struct hist_entry_iter *iter __maybe_unused,
702 * cumulated only one time to prevent entries more than 100% 720 * cumulated only one time to prevent entries more than 100%
703 * overhead. 721 * overhead.
704 */ 722 */
705 he_cache = malloc(sizeof(*he_cache) * (PERF_MAX_STACK_DEPTH + 1)); 723 he_cache = malloc(sizeof(*he_cache) * (iter->max_stack + 1));
706 if (he_cache == NULL) 724 if (he_cache == NULL)
707 return -ENOMEM; 725 return -ENOMEM;
708 726
@@ -863,6 +881,8 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
863 if (err) 881 if (err)
864 return err; 882 return err;
865 883
884 iter->max_stack = max_stack_depth;
885
866 err = iter->ops->prepare_entry(iter, al); 886 err = iter->ops->prepare_entry(iter, al);
867 if (err) 887 if (err)
868 goto out; 888 goto out;
@@ -1024,6 +1044,7 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
1024 hists__filter_entry_by_dso(hists, he); 1044 hists__filter_entry_by_dso(hists, he);
1025 hists__filter_entry_by_thread(hists, he); 1045 hists__filter_entry_by_thread(hists, he);
1026 hists__filter_entry_by_symbol(hists, he); 1046 hists__filter_entry_by_symbol(hists, he);
1047 hists__filter_entry_by_socket(hists, he);
1027} 1048}
1028 1049
1029void hists__collapse_resort(struct hists *hists, struct ui_progress *prog) 1050void hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
@@ -1143,7 +1164,7 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog)
1143 struct perf_evsel *evsel = hists_to_evsel(hists); 1164 struct perf_evsel *evsel = hists_to_evsel(hists);
1144 bool use_callchain; 1165 bool use_callchain;
1145 1166
1146 if (evsel && !symbol_conf.show_ref_callgraph) 1167 if (evsel && symbol_conf.use_callchain && !symbol_conf.show_ref_callgraph)
1147 use_callchain = evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN; 1168 use_callchain = evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN;
1148 else 1169 else
1149 use_callchain = symbol_conf.use_callchain; 1170 use_callchain = symbol_conf.use_callchain;
@@ -1292,6 +1313,37 @@ void hists__filter_by_symbol(struct hists *hists)
1292 } 1313 }
1293} 1314}
1294 1315
1316static bool hists__filter_entry_by_socket(struct hists *hists,
1317 struct hist_entry *he)
1318{
1319 if ((hists->socket_filter > -1) &&
1320 (he->socket != hists->socket_filter)) {
1321 he->filtered |= (1 << HIST_FILTER__SOCKET);
1322 return true;
1323 }
1324
1325 return false;
1326}
1327
1328void hists__filter_by_socket(struct hists *hists)
1329{
1330 struct rb_node *nd;
1331
1332 hists->stats.nr_non_filtered_samples = 0;
1333
1334 hists__reset_filter_stats(hists);
1335 hists__reset_col_len(hists);
1336
1337 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
1338 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
1339
1340 if (hists__filter_entry_by_socket(hists, h))
1341 continue;
1342
1343 hists__remove_entry_filter(hists, h, HIST_FILTER__SOCKET);
1344 }
1345}
1346
1295void events_stats__inc(struct events_stats *stats, u32 type) 1347void events_stats__inc(struct events_stats *stats, u32 type)
1296{ 1348{
1297 ++stats->nr_events[0]; 1349 ++stats->nr_events[0];
@@ -1517,6 +1569,7 @@ static int hists_evsel__init(struct perf_evsel *evsel)
1517 hists->entries_collapsed = RB_ROOT; 1569 hists->entries_collapsed = RB_ROOT;
1518 hists->entries = RB_ROOT; 1570 hists->entries = RB_ROOT;
1519 pthread_mutex_init(&hists->lock, NULL); 1571 pthread_mutex_init(&hists->lock, NULL);
1572 hists->socket_filter = -1;
1520 return 0; 1573 return 0;
1521} 1574}
1522 1575
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index de6d58e7f0d5..a48a2078d288 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -20,6 +20,7 @@ enum hist_filter {
20 HIST_FILTER__SYMBOL, 20 HIST_FILTER__SYMBOL,
21 HIST_FILTER__GUEST, 21 HIST_FILTER__GUEST,
22 HIST_FILTER__HOST, 22 HIST_FILTER__HOST,
23 HIST_FILTER__SOCKET,
23}; 24};
24 25
25enum hist_column { 26enum hist_column {
@@ -29,6 +30,7 @@ enum hist_column {
29 HISTC_COMM, 30 HISTC_COMM,
30 HISTC_PARENT, 31 HISTC_PARENT,
31 HISTC_CPU, 32 HISTC_CPU,
33 HISTC_SOCKET,
32 HISTC_SRCLINE, 34 HISTC_SRCLINE,
33 HISTC_SRCFILE, 35 HISTC_SRCFILE,
34 HISTC_MISPREDICT, 36 HISTC_MISPREDICT,
@@ -47,6 +49,7 @@ enum hist_column {
47 HISTC_MEM_LVL, 49 HISTC_MEM_LVL,
48 HISTC_MEM_SNOOP, 50 HISTC_MEM_SNOOP,
49 HISTC_MEM_DCACHELINE, 51 HISTC_MEM_DCACHELINE,
52 HISTC_MEM_IADDR_SYMBOL,
50 HISTC_TRANSACTION, 53 HISTC_TRANSACTION,
51 HISTC_CYCLES, 54 HISTC_CYCLES,
52 HISTC_NR_COLS, /* Last entry */ 55 HISTC_NR_COLS, /* Last entry */
@@ -70,6 +73,7 @@ struct hists {
70 struct events_stats stats; 73 struct events_stats stats;
71 u64 event_stream; 74 u64 event_stream;
72 u16 col_len[HISTC_NR_COLS]; 75 u16 col_len[HISTC_NR_COLS];
76 int socket_filter;
73}; 77};
74 78
75struct hist_entry_iter; 79struct hist_entry_iter;
@@ -87,6 +91,7 @@ struct hist_entry_iter {
87 int curr; 91 int curr;
88 92
89 bool hide_unresolved; 93 bool hide_unresolved;
94 int max_stack;
90 95
91 struct perf_evsel *evsel; 96 struct perf_evsel *evsel;
92 struct perf_sample *sample; 97 struct perf_sample *sample;
@@ -144,11 +149,12 @@ size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp);
144void hists__filter_by_dso(struct hists *hists); 149void hists__filter_by_dso(struct hists *hists);
145void hists__filter_by_thread(struct hists *hists); 150void hists__filter_by_thread(struct hists *hists);
146void hists__filter_by_symbol(struct hists *hists); 151void hists__filter_by_symbol(struct hists *hists);
152void hists__filter_by_socket(struct hists *hists);
147 153
148static inline bool hists__has_filter(struct hists *hists) 154static inline bool hists__has_filter(struct hists *hists)
149{ 155{
150 return hists->thread_filter || hists->dso_filter || 156 return hists->thread_filter || hists->dso_filter ||
151 hists->symbol_filter_str; 157 hists->symbol_filter_str || (hists->socket_filter > -1);
152} 158}
153 159
154u16 hists__col_len(struct hists *hists, enum hist_column col); 160u16 hists__col_len(struct hists *hists, enum hist_column col);
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 8f149655f497..07c644ed64c4 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -5,4 +5,12 @@
5const char *get_arch_regstr(unsigned int n); 5const char *get_arch_regstr(unsigned int n);
6#endif 6#endif
7 7
8#ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
9/*
10 * Arch should support fetching the offset of a register in pt_regs
11 * by its name. See kernel's regs_query_register_offset in
12 * arch/xxx/kernel/ptrace.c.
13 */
14int regs_query_register_offset(const char *name);
15#endif
8#endif 16#endif
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index ea768625ab5b..eb0e7f8bf515 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -623,7 +623,7 @@ static int intel_bts_process_event(struct perf_session *session,
623 if (err) 623 if (err)
624 return err; 624 return err;
625 if (event->header.type == PERF_RECORD_EXIT) { 625 if (event->header.type == PERF_RECORD_EXIT) {
626 err = intel_bts_process_tid_exit(bts, event->comm.tid); 626 err = intel_bts_process_tid_exit(bts, event->fork.tid);
627 if (err) 627 if (err)
628 return err; 628 return err;
629 } 629 }
diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build
index 2386322ece4f..0611d619a42e 100644
--- a/tools/perf/util/intel-pt-decoder/Build
+++ b/tools/perf/util/intel-pt-decoder/Build
@@ -7,6 +7,17 @@ $(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$(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/inat.c $(OUTPUT)util/intel-pt-decoder/inat-tables.c 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
11 @(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 && \
13 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 && \
15 diff -B util/intel-pt-decoder/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null && \
16 diff -B -I'^#include' util/intel-pt-decoder/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \
17 diff -B -I'^#include' util/intel-pt-decoder/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \
18 diff -B -I'^#include' util/intel-pt-decoder/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \
19 || echo "Warning: Intel PT: x86 instruction decoder differs from kernel" >&2 )) || true
20 $(call rule_mkdir)
21 $(call if_changed_dep,cc_o_c)
11 22
12CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder -Wno-override-init 23CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder -Wno-override-init
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 22ba50224319..9409d014b46c 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -650,7 +650,7 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
650 if (data->from_mtc && timestamp < data->timestamp && 650 if (data->from_mtc && timestamp < data->timestamp &&
651 data->timestamp - timestamp < decoder->tsc_slip) 651 data->timestamp - timestamp < decoder->tsc_slip)
652 return 1; 652 return 1;
653 while (timestamp < data->timestamp) 653 if (timestamp < data->timestamp)
654 timestamp += (1ULL << 56); 654 timestamp += (1ULL << 56);
655 if (pkt_info->last_packet_type != INTEL_PT_CYC) { 655 if (pkt_info->last_packet_type != INTEL_PT_CYC) {
656 if (data->from_mtc) 656 if (data->from_mtc)
@@ -1191,7 +1191,7 @@ static void intel_pt_calc_tsc_timestamp(struct intel_pt_decoder *decoder)
1191 timestamp); 1191 timestamp);
1192 timestamp = decoder->timestamp; 1192 timestamp = decoder->timestamp;
1193 } 1193 }
1194 while (timestamp < decoder->timestamp) { 1194 if (timestamp < decoder->timestamp) {
1195 intel_pt_log_to("Wraparound timestamp", timestamp); 1195 intel_pt_log_to("Wraparound timestamp", timestamp);
1196 timestamp += (1ULL << 56); 1196 timestamp += (1ULL << 56);
1197 decoder->tsc_timestamp = timestamp; 1197 decoder->tsc_timestamp = timestamp;
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-log.c b/tools/perf/util/intel-pt-decoder/intel-pt-log.c
index d09c7d9f9050..319bef33a64b 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-log.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-log.c
@@ -29,18 +29,18 @@
29 29
30static FILE *f; 30static FILE *f;
31static char log_name[MAX_LOG_NAME]; 31static char log_name[MAX_LOG_NAME];
32static bool enable_logging; 32bool intel_pt_enable_logging;
33 33
34void intel_pt_log_enable(void) 34void intel_pt_log_enable(void)
35{ 35{
36 enable_logging = true; 36 intel_pt_enable_logging = true;
37} 37}
38 38
39void intel_pt_log_disable(void) 39void intel_pt_log_disable(void)
40{ 40{
41 if (f) 41 if (f)
42 fflush(f); 42 fflush(f);
43 enable_logging = false; 43 intel_pt_enable_logging = false;
44} 44}
45 45
46void intel_pt_log_set_name(const char *name) 46void intel_pt_log_set_name(const char *name)
@@ -80,7 +80,7 @@ static void intel_pt_print_no_data(uint64_t pos, int indent)
80 80
81static int intel_pt_log_open(void) 81static int intel_pt_log_open(void)
82{ 82{
83 if (!enable_logging) 83 if (!intel_pt_enable_logging)
84 return -1; 84 return -1;
85 85
86 if (f) 86 if (f)
@@ -91,15 +91,15 @@ static int intel_pt_log_open(void)
91 91
92 f = fopen(log_name, "w+"); 92 f = fopen(log_name, "w+");
93 if (!f) { 93 if (!f) {
94 enable_logging = false; 94 intel_pt_enable_logging = false;
95 return -1; 95 return -1;
96 } 96 }
97 97
98 return 0; 98 return 0;
99} 99}
100 100
101void intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len, 101void __intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len,
102 uint64_t pos, const unsigned char *buf) 102 uint64_t pos, const unsigned char *buf)
103{ 103{
104 char desc[INTEL_PT_PKT_DESC_MAX]; 104 char desc[INTEL_PT_PKT_DESC_MAX];
105 105
@@ -111,7 +111,7 @@ void intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len,
111 fprintf(f, "%s\n", desc); 111 fprintf(f, "%s\n", desc);
112} 112}
113 113
114void intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip) 114void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip)
115{ 115{
116 char desc[INTEL_PT_INSN_DESC_MAX]; 116 char desc[INTEL_PT_INSN_DESC_MAX];
117 size_t len = intel_pt_insn->length; 117 size_t len = intel_pt_insn->length;
@@ -128,7 +128,8 @@ void intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip)
128 fprintf(f, "Bad instruction!\n"); 128 fprintf(f, "Bad instruction!\n");
129} 129}
130 130
131void intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, uint64_t ip) 131void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn,
132 uint64_t ip)
132{ 133{
133 char desc[INTEL_PT_INSN_DESC_MAX]; 134 char desc[INTEL_PT_INSN_DESC_MAX];
134 135
@@ -142,7 +143,7 @@ void intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, uint64_t ip)
142 fprintf(f, "Bad instruction!\n"); 143 fprintf(f, "Bad instruction!\n");
143} 144}
144 145
145void intel_pt_log(const char *fmt, ...) 146void __intel_pt_log(const char *fmt, ...)
146{ 147{
147 va_list args; 148 va_list args;
148 149
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-log.h b/tools/perf/util/intel-pt-decoder/intel-pt-log.h
index db3942f83677..debe751dc3d6 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-log.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-log.h
@@ -25,20 +25,46 @@ void intel_pt_log_enable(void);
25void intel_pt_log_disable(void); 25void intel_pt_log_disable(void);
26void intel_pt_log_set_name(const char *name); 26void intel_pt_log_set_name(const char *name);
27 27
28void intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len, 28void __intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len,
29 uint64_t pos, const unsigned char *buf); 29 uint64_t pos, const unsigned char *buf);
30 30
31struct intel_pt_insn; 31struct intel_pt_insn;
32 32
33void intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip); 33void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip);
34void intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, 34void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn,
35 uint64_t ip); 35 uint64_t ip);
36 36
37__attribute__((format(printf, 1, 2))) 37__attribute__((format(printf, 1, 2)))
38void intel_pt_log(const char *fmt, ...); 38void __intel_pt_log(const char *fmt, ...);
39
40#define intel_pt_log(fmt, ...) \
41 do { \
42 if (intel_pt_enable_logging) \
43 __intel_pt_log(fmt, ##__VA_ARGS__); \
44 } while (0)
45
46#define intel_pt_log_packet(arg, ...) \
47 do { \
48 if (intel_pt_enable_logging) \
49 __intel_pt_log_packet(arg, ##__VA_ARGS__); \
50 } while (0)
51
52#define intel_pt_log_insn(arg, ...) \
53 do { \
54 if (intel_pt_enable_logging) \
55 __intel_pt_log_insn(arg, ##__VA_ARGS__); \
56 } while (0)
57
58#define intel_pt_log_insn_no_data(arg, ...) \
59 do { \
60 if (intel_pt_enable_logging) \
61 __intel_pt_log_insn_no_data(arg, ##__VA_ARGS__); \
62 } while (0)
39 63
40#define x64_fmt "0x%" PRIx64 64#define x64_fmt "0x%" PRIx64
41 65
66extern bool intel_pt_enable_logging;
67
42static inline void intel_pt_log_at(const char *msg, uint64_t u) 68static inline void intel_pt_log_at(const char *msg, uint64_t u)
43{ 69{
44 intel_pt_log("%s at " x64_fmt "\n", msg, u); 70 intel_pt_log("%s at " x64_fmt "\n", msg, u);
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 816488c0b97e..d388de72eaca 100644
--- a/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
+++ b/tools/perf/util/intel-pt-decoder/x86-opcode-map.txt
@@ -353,8 +353,12 @@ AVXcode: 1
35317: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1) 35317: vmovhps Mq,Vq (v1) | vmovhpd Mq,Vq (66),(v1)
35418: Grp16 (1A) 35418: Grp16 (1A)
35519: 35519:
3561a: BNDCL Ev,Gv | BNDCU Ev,Gv | BNDMOV Gv,Ev | BNDLDX Gv,Ev,Gv 356# Intel SDM opcode map does not list MPX instructions. For now using Gv for
3571b: BNDCN Ev,Gv | BNDMOV Ev,Gv | BNDMK Gv,Ev | BNDSTX Ev,GV,Gv 357# bnd registers and Ev for everything else is OK because the instruction
358# decoder does not use the information except as an indication that there is
359# a ModR/M byte.
3601a: BNDCL Gv,Ev (F3) | BNDCU Gv,Ev (F2) | BNDMOV Gv,Ev (66) | BNDLDX Gv,Ev
3611b: BNDCN Gv,Ev (F2) | BNDMOV Ev,Gv (66) | BNDMK Gv,Ev (F3) | BNDSTX Ev,Gv
3581c: 3621c:
3591d: 3631d:
3601e: 3641e:
@@ -732,6 +736,12 @@ bd: vfnmadd231ss/d Vx,Hx,Wx (66),(v),(v1)
732be: vfnmsub231ps/d Vx,Hx,Wx (66),(v) 736be: vfnmsub231ps/d Vx,Hx,Wx (66),(v)
733bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1) 737bf: vfnmsub231ss/d Vx,Hx,Wx (66),(v),(v1)
734# 0x0f 0x38 0xc0-0xff 738# 0x0f 0x38 0xc0-0xff
739c8: sha1nexte Vdq,Wdq
740c9: sha1msg1 Vdq,Wdq
741ca: sha1msg2 Vdq,Wdq
742cb: sha256rnds2 Vdq,Wdq
743cc: sha256msg1 Vdq,Wdq
744cd: sha256msg2 Vdq,Wdq
735db: VAESIMC Vdq,Wdq (66),(v1) 745db: VAESIMC Vdq,Wdq (66),(v1)
736dc: VAESENC Vdq,Hdq,Wdq (66),(v1) 746dc: VAESENC Vdq,Hdq,Wdq (66),(v1)
737dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1) 747dd: VAESENCLAST Vdq,Hdq,Wdq (66),(v1)
@@ -790,6 +800,7 @@ AVXcode: 3
79061: vpcmpestri Vdq,Wdq,Ib (66),(v1) 80061: vpcmpestri Vdq,Wdq,Ib (66),(v1)
79162: vpcmpistrm Vdq,Wdq,Ib (66),(v1) 80162: vpcmpistrm Vdq,Wdq,Ib (66),(v1)
79263: vpcmpistri Vdq,Wdq,Ib (66),(v1) 80263: vpcmpistri Vdq,Wdq,Ib (66),(v1)
803cc: sha1rnds4 Vdq,Wdq,Ib
793df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1) 804df: VAESKEYGEN Vdq,Wdq,Ib (66),(v1)
794f0: RORX Gy,Ey,Ib (F2),(v) 805f0: RORX Gy,Ey,Ib (F2),(v)
795EndTable 806EndTable
@@ -874,7 +885,7 @@ GrpTable: Grp7
8742: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B) 8852: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B) | VMFUNC (100),(11B) | XEND (101)(11B) | XTEST (110)(11B)
8753: LIDT Ms 8863: LIDT Ms
8764: SMSW Mw/Rv 8874: SMSW Mw/Rv
8775: 8885: rdpkru (110),(11B) | wrpkru (111),(11B)
8786: LMSW Ew 8896: LMSW Ew
8797: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B) 8907: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
880EndTable 891EndTable
@@ -888,6 +899,9 @@ EndTable
888 899
889GrpTable: Grp9 900GrpTable: Grp9
8901: CMPXCHG8B/16B Mq/Mdq 9011: CMPXCHG8B/16B Mq/Mdq
9023: xrstors
9034: xsavec
9045: xsaves
8916: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B) 9056: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3) | RDRAND Rv (11B)
8927: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B) 9067: VMPTRST Mq | VMPTRST Mq (F3) | RDSEED Rv (11B)
893EndTable 907EndTable
@@ -932,8 +946,8 @@ GrpTable: Grp15
9323: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) 9463: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
9334: XSAVE 9474: XSAVE
9345: XRSTOR | lfence (11B) 9485: XRSTOR | lfence (11B)
9356: XSAVEOPT | mfence (11B) 9496: XSAVEOPT | clwb (66) | mfence (11B)
9367: clflush | sfence (11B) 9507: clflush | clflushopt (66) | sfence (11B) | pcommit (66),(11B)
937EndTable 951EndTable
938 952
939GrpTable: Grp16 953GrpTable: Grp16
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index bb41c20e6005..97f963a3dcb9 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -22,6 +22,7 @@
22#include "../perf.h" 22#include "../perf.h"
23#include "session.h" 23#include "session.h"
24#include "machine.h" 24#include "machine.h"
25#include "sort.h"
25#include "tool.h" 26#include "tool.h"
26#include "event.h" 27#include "event.h"
27#include "evlist.h" 28#include "evlist.h"
@@ -63,6 +64,7 @@ struct intel_pt {
63 bool data_queued; 64 bool data_queued;
64 bool est_tsc; 65 bool est_tsc;
65 bool sync_switch; 66 bool sync_switch;
67 bool mispred_all;
66 int have_sched_switch; 68 int have_sched_switch;
67 u32 pmu_type; 69 u32 pmu_type;
68 u64 kernel_start; 70 u64 kernel_start;
@@ -115,6 +117,9 @@ struct intel_pt_queue {
115 void *decoder; 117 void *decoder;
116 const struct intel_pt_state *state; 118 const struct intel_pt_state *state;
117 struct ip_callchain *chain; 119 struct ip_callchain *chain;
120 struct branch_stack *last_branch;
121 struct branch_stack *last_branch_rb;
122 size_t last_branch_pos;
118 union perf_event *event_buf; 123 union perf_event *event_buf;
119 bool on_heap; 124 bool on_heap;
120 bool stop; 125 bool stop;
@@ -675,6 +680,19 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
675 goto out_free; 680 goto out_free;
676 } 681 }
677 682
683 if (pt->synth_opts.last_branch) {
684 size_t sz = sizeof(struct branch_stack);
685
686 sz += pt->synth_opts.last_branch_sz *
687 sizeof(struct branch_entry);
688 ptq->last_branch = zalloc(sz);
689 if (!ptq->last_branch)
690 goto out_free;
691 ptq->last_branch_rb = zalloc(sz);
692 if (!ptq->last_branch_rb)
693 goto out_free;
694 }
695
678 ptq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE); 696 ptq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
679 if (!ptq->event_buf) 697 if (!ptq->event_buf)
680 goto out_free; 698 goto out_free;
@@ -720,7 +738,7 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
720 738
721 if (!params.period) { 739 if (!params.period) {
722 params.period_type = INTEL_PT_PERIOD_INSTRUCTIONS; 740 params.period_type = INTEL_PT_PERIOD_INSTRUCTIONS;
723 params.period = 1000; 741 params.period = 1;
724 } 742 }
725 } 743 }
726 744
@@ -732,6 +750,8 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
732 750
733out_free: 751out_free:
734 zfree(&ptq->event_buf); 752 zfree(&ptq->event_buf);
753 zfree(&ptq->last_branch);
754 zfree(&ptq->last_branch_rb);
735 zfree(&ptq->chain); 755 zfree(&ptq->chain);
736 free(ptq); 756 free(ptq);
737 return NULL; 757 return NULL;
@@ -746,6 +766,8 @@ static void intel_pt_free_queue(void *priv)
746 thread__zput(ptq->thread); 766 thread__zput(ptq->thread);
747 intel_pt_decoder_free(ptq->decoder); 767 intel_pt_decoder_free(ptq->decoder);
748 zfree(&ptq->event_buf); 768 zfree(&ptq->event_buf);
769 zfree(&ptq->last_branch);
770 zfree(&ptq->last_branch_rb);
749 zfree(&ptq->chain); 771 zfree(&ptq->chain);
750 free(ptq); 772 free(ptq);
751} 773}
@@ -876,6 +898,58 @@ static int intel_pt_setup_queues(struct intel_pt *pt)
876 return 0; 898 return 0;
877} 899}
878 900
901static inline void intel_pt_copy_last_branch_rb(struct intel_pt_queue *ptq)
902{
903 struct branch_stack *bs_src = ptq->last_branch_rb;
904 struct branch_stack *bs_dst = ptq->last_branch;
905 size_t nr = 0;
906
907 bs_dst->nr = bs_src->nr;
908
909 if (!bs_src->nr)
910 return;
911
912 nr = ptq->pt->synth_opts.last_branch_sz - ptq->last_branch_pos;
913 memcpy(&bs_dst->entries[0],
914 &bs_src->entries[ptq->last_branch_pos],
915 sizeof(struct branch_entry) * nr);
916
917 if (bs_src->nr >= ptq->pt->synth_opts.last_branch_sz) {
918 memcpy(&bs_dst->entries[nr],
919 &bs_src->entries[0],
920 sizeof(struct branch_entry) * ptq->last_branch_pos);
921 }
922}
923
924static inline void intel_pt_reset_last_branch_rb(struct intel_pt_queue *ptq)
925{
926 ptq->last_branch_pos = 0;
927 ptq->last_branch_rb->nr = 0;
928}
929
930static void intel_pt_update_last_branch_rb(struct intel_pt_queue *ptq)
931{
932 const struct intel_pt_state *state = ptq->state;
933 struct branch_stack *bs = ptq->last_branch_rb;
934 struct branch_entry *be;
935
936 if (!ptq->last_branch_pos)
937 ptq->last_branch_pos = ptq->pt->synth_opts.last_branch_sz;
938
939 ptq->last_branch_pos -= 1;
940
941 be = &bs->entries[ptq->last_branch_pos];
942 be->from = state->from_ip;
943 be->to = state->to_ip;
944 be->flags.abort = !!(state->flags & INTEL_PT_ABORT_TX);
945 be->flags.in_tx = !!(state->flags & INTEL_PT_IN_TX);
946 /* No support for mispredict */
947 be->flags.mispred = ptq->pt->mispred_all;
948
949 if (bs->nr < ptq->pt->synth_opts.last_branch_sz)
950 bs->nr += 1;
951}
952
879static int intel_pt_inject_event(union perf_event *event, 953static int intel_pt_inject_event(union perf_event *event,
880 struct perf_sample *sample, u64 type, 954 struct perf_sample *sample, u64 type,
881 bool swapped) 955 bool swapped)
@@ -890,6 +964,13 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
890 struct intel_pt *pt = ptq->pt; 964 struct intel_pt *pt = ptq->pt;
891 union perf_event *event = ptq->event_buf; 965 union perf_event *event = ptq->event_buf;
892 struct perf_sample sample = { .ip = 0, }; 966 struct perf_sample sample = { .ip = 0, };
967 struct dummy_branch_stack {
968 u64 nr;
969 struct branch_entry entries;
970 } dummy_bs;
971
972 if (pt->branches_filter && !(pt->branches_filter & ptq->flags))
973 return 0;
893 974
894 event->sample.header.type = PERF_RECORD_SAMPLE; 975 event->sample.header.type = PERF_RECORD_SAMPLE;
895 event->sample.header.misc = PERF_RECORD_MISC_USER; 976 event->sample.header.misc = PERF_RECORD_MISC_USER;
@@ -909,8 +990,20 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
909 sample.flags = ptq->flags; 990 sample.flags = ptq->flags;
910 sample.insn_len = ptq->insn_len; 991 sample.insn_len = ptq->insn_len;
911 992
912 if (pt->branches_filter && !(pt->branches_filter & ptq->flags)) 993 /*
913 return 0; 994 * perf report cannot handle events without a branch stack when using
995 * SORT_MODE__BRANCH so make a dummy one.
996 */
997 if (pt->synth_opts.last_branch && sort__mode == SORT_MODE__BRANCH) {
998 dummy_bs = (struct dummy_branch_stack){
999 .nr = 1,
1000 .entries = {
1001 .from = sample.ip,
1002 .to = sample.addr,
1003 },
1004 };
1005 sample.branch_stack = (struct branch_stack *)&dummy_bs;
1006 }
914 1007
915 if (pt->synth_opts.inject) { 1008 if (pt->synth_opts.inject) {
916 ret = intel_pt_inject_event(event, &sample, 1009 ret = intel_pt_inject_event(event, &sample,
@@ -961,6 +1054,11 @@ static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
961 sample.callchain = ptq->chain; 1054 sample.callchain = ptq->chain;
962 } 1055 }
963 1056
1057 if (pt->synth_opts.last_branch) {
1058 intel_pt_copy_last_branch_rb(ptq);
1059 sample.branch_stack = ptq->last_branch;
1060 }
1061
964 if (pt->synth_opts.inject) { 1062 if (pt->synth_opts.inject) {
965 ret = intel_pt_inject_event(event, &sample, 1063 ret = intel_pt_inject_event(event, &sample,
966 pt->instructions_sample_type, 1064 pt->instructions_sample_type,
@@ -974,6 +1072,9 @@ static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
974 pr_err("Intel Processor Trace: failed to deliver instruction event, error %d\n", 1072 pr_err("Intel Processor Trace: failed to deliver instruction event, error %d\n",
975 ret); 1073 ret);
976 1074
1075 if (pt->synth_opts.last_branch)
1076 intel_pt_reset_last_branch_rb(ptq);
1077
977 return ret; 1078 return ret;
978} 1079}
979 1080
@@ -1008,6 +1109,11 @@ static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
1008 sample.callchain = ptq->chain; 1109 sample.callchain = ptq->chain;
1009 } 1110 }
1010 1111
1112 if (pt->synth_opts.last_branch) {
1113 intel_pt_copy_last_branch_rb(ptq);
1114 sample.branch_stack = ptq->last_branch;
1115 }
1116
1011 if (pt->synth_opts.inject) { 1117 if (pt->synth_opts.inject) {
1012 ret = intel_pt_inject_event(event, &sample, 1118 ret = intel_pt_inject_event(event, &sample,
1013 pt->transactions_sample_type, 1119 pt->transactions_sample_type,
@@ -1021,6 +1127,9 @@ static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
1021 pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n", 1127 pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n",
1022 ret); 1128 ret);
1023 1129
1130 if (pt->synth_opts.callchain)
1131 intel_pt_reset_last_branch_rb(ptq);
1132
1024 return ret; 1133 return ret;
1025} 1134}
1026 1135
@@ -1116,6 +1225,9 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
1116 return err; 1225 return err;
1117 } 1226 }
1118 1227
1228 if (pt->synth_opts.last_branch)
1229 intel_pt_update_last_branch_rb(ptq);
1230
1119 if (!pt->sync_switch) 1231 if (!pt->sync_switch)
1120 return 0; 1232 return 0;
1121 1233
@@ -1145,16 +1257,18 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
1145 return 0; 1257 return 0;
1146} 1258}
1147 1259
1148static u64 intel_pt_switch_ip(struct machine *machine, u64 *ptss_ip) 1260static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
1149{ 1261{
1262 struct machine *machine = pt->machine;
1150 struct map *map; 1263 struct map *map;
1151 struct symbol *sym, *start; 1264 struct symbol *sym, *start;
1152 u64 ip, switch_ip = 0; 1265 u64 ip, switch_ip = 0;
1266 const char *ptss;
1153 1267
1154 if (ptss_ip) 1268 if (ptss_ip)
1155 *ptss_ip = 0; 1269 *ptss_ip = 0;
1156 1270
1157 map = machine__kernel_map(machine, MAP__FUNCTION); 1271 map = machine__kernel_map(machine);
1158 if (!map) 1272 if (!map)
1159 return 0; 1273 return 0;
1160 1274
@@ -1177,8 +1291,13 @@ static u64 intel_pt_switch_ip(struct machine *machine, u64 *ptss_ip)
1177 if (!switch_ip || !ptss_ip) 1291 if (!switch_ip || !ptss_ip)
1178 return 0; 1292 return 0;
1179 1293
1294 if (pt->have_sched_switch == 1)
1295 ptss = "perf_trace_sched_switch";
1296 else
1297 ptss = "__perf_event_task_sched_out";
1298
1180 for (sym = start; sym; sym = dso__next_symbol(sym)) { 1299 for (sym = start; sym; sym = dso__next_symbol(sym)) {
1181 if (!strcmp(sym->name, "perf_trace_sched_switch")) { 1300 if (!strcmp(sym->name, ptss)) {
1182 ip = map->unmap_ip(map, sym->start); 1301 ip = map->unmap_ip(map, sym->start);
1183 if (ip >= map->start && ip < map->end) { 1302 if (ip >= map->start && ip < map->end) {
1184 *ptss_ip = ip; 1303 *ptss_ip = ip;
@@ -1198,11 +1317,11 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp)
1198 1317
1199 if (!pt->kernel_start) { 1318 if (!pt->kernel_start) {
1200 pt->kernel_start = machine__kernel_start(pt->machine); 1319 pt->kernel_start = machine__kernel_start(pt->machine);
1201 if (pt->per_cpu_mmaps && pt->have_sched_switch && 1320 if (pt->per_cpu_mmaps &&
1321 (pt->have_sched_switch == 1 || pt->have_sched_switch == 3) &&
1202 !pt->timeless_decoding && intel_pt_tracing_kernel(pt) && 1322 !pt->timeless_decoding && intel_pt_tracing_kernel(pt) &&
1203 !pt->sampling_mode) { 1323 !pt->sampling_mode) {
1204 pt->switch_ip = intel_pt_switch_ip(pt->machine, 1324 pt->switch_ip = intel_pt_switch_ip(pt, &pt->ptss_ip);
1205 &pt->ptss_ip);
1206 if (pt->switch_ip) { 1325 if (pt->switch_ip) {
1207 intel_pt_log("switch_ip: %"PRIx64" ptss_ip: %"PRIx64"\n", 1326 intel_pt_log("switch_ip: %"PRIx64" ptss_ip: %"PRIx64"\n",
1208 pt->switch_ip, pt->ptss_ip); 1327 pt->switch_ip, pt->ptss_ip);
@@ -1387,31 +1506,18 @@ static struct intel_pt_queue *intel_pt_cpu_to_ptq(struct intel_pt *pt, int cpu)
1387 return NULL; 1506 return NULL;
1388} 1507}
1389 1508
1390static int intel_pt_process_switch(struct intel_pt *pt, 1509static int intel_pt_sync_switch(struct intel_pt *pt, int cpu, pid_t tid,
1391 struct perf_sample *sample) 1510 u64 timestamp)
1392{ 1511{
1393 struct intel_pt_queue *ptq; 1512 struct intel_pt_queue *ptq;
1394 struct perf_evsel *evsel; 1513 int err;
1395 pid_t tid;
1396 int cpu, err;
1397
1398 evsel = perf_evlist__id2evsel(pt->session->evlist, sample->id);
1399 if (evsel != pt->switch_evsel)
1400 return 0;
1401
1402 tid = perf_evsel__intval(evsel, sample, "next_pid");
1403 cpu = sample->cpu;
1404
1405 intel_pt_log("sched_switch: cpu %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
1406 cpu, tid, sample->time, perf_time_to_tsc(sample->time,
1407 &pt->tc));
1408 1514
1409 if (!pt->sync_switch) 1515 if (!pt->sync_switch)
1410 goto out; 1516 return 1;
1411 1517
1412 ptq = intel_pt_cpu_to_ptq(pt, cpu); 1518 ptq = intel_pt_cpu_to_ptq(pt, cpu);
1413 if (!ptq) 1519 if (!ptq)
1414 goto out; 1520 return 1;
1415 1521
1416 switch (ptq->switch_state) { 1522 switch (ptq->switch_state) {
1417 case INTEL_PT_SS_NOT_TRACING: 1523 case INTEL_PT_SS_NOT_TRACING:
@@ -1424,7 +1530,7 @@ static int intel_pt_process_switch(struct intel_pt *pt,
1424 return 0; 1530 return 0;
1425 case INTEL_PT_SS_EXPECTING_SWITCH_EVENT: 1531 case INTEL_PT_SS_EXPECTING_SWITCH_EVENT:
1426 if (!ptq->on_heap) { 1532 if (!ptq->on_heap) {
1427 ptq->timestamp = perf_time_to_tsc(sample->time, 1533 ptq->timestamp = perf_time_to_tsc(timestamp,
1428 &pt->tc); 1534 &pt->tc);
1429 err = auxtrace_heap__add(&pt->heap, ptq->queue_nr, 1535 err = auxtrace_heap__add(&pt->heap, ptq->queue_nr,
1430 ptq->timestamp); 1536 ptq->timestamp);
@@ -1441,10 +1547,76 @@ static int intel_pt_process_switch(struct intel_pt *pt,
1441 default: 1547 default:
1442 break; 1548 break;
1443 } 1549 }
1444out: 1550
1551 return 1;
1552}
1553
1554static int intel_pt_process_switch(struct intel_pt *pt,
1555 struct perf_sample *sample)
1556{
1557 struct perf_evsel *evsel;
1558 pid_t tid;
1559 int cpu, ret;
1560
1561 evsel = perf_evlist__id2evsel(pt->session->evlist, sample->id);
1562 if (evsel != pt->switch_evsel)
1563 return 0;
1564
1565 tid = perf_evsel__intval(evsel, sample, "next_pid");
1566 cpu = sample->cpu;
1567
1568 intel_pt_log("sched_switch: cpu %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
1569 cpu, tid, sample->time, perf_time_to_tsc(sample->time,
1570 &pt->tc));
1571
1572 ret = intel_pt_sync_switch(pt, cpu, tid, sample->time);
1573 if (ret <= 0)
1574 return ret;
1575
1445 return machine__set_current_tid(pt->machine, cpu, -1, tid); 1576 return machine__set_current_tid(pt->machine, cpu, -1, tid);
1446} 1577}
1447 1578
1579static int intel_pt_context_switch(struct intel_pt *pt, union perf_event *event,
1580 struct perf_sample *sample)
1581{
1582 bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
1583 pid_t pid, tid;
1584 int cpu, ret;
1585
1586 cpu = sample->cpu;
1587
1588 if (pt->have_sched_switch == 3) {
1589 if (!out)
1590 return 0;
1591 if (event->header.type != PERF_RECORD_SWITCH_CPU_WIDE) {
1592 pr_err("Expecting CPU-wide context switch event\n");
1593 return -EINVAL;
1594 }
1595 pid = event->context_switch.next_prev_pid;
1596 tid = event->context_switch.next_prev_tid;
1597 } else {
1598 if (out)
1599 return 0;
1600 pid = sample->pid;
1601 tid = sample->tid;
1602 }
1603
1604 if (tid == -1) {
1605 pr_err("context_switch event has no tid\n");
1606 return -EINVAL;
1607 }
1608
1609 intel_pt_log("context_switch: cpu %d pid %d tid %d time %"PRIu64" tsc %#"PRIx64"\n",
1610 cpu, pid, tid, sample->time, perf_time_to_tsc(sample->time,
1611 &pt->tc));
1612
1613 ret = intel_pt_sync_switch(pt, cpu, tid, sample->time);
1614 if (ret <= 0)
1615 return ret;
1616
1617 return machine__set_current_tid(pt->machine, cpu, pid, tid);
1618}
1619
1448static int intel_pt_process_itrace_start(struct intel_pt *pt, 1620static int intel_pt_process_itrace_start(struct intel_pt *pt,
1449 union perf_event *event, 1621 union perf_event *event,
1450 struct perf_sample *sample) 1622 struct perf_sample *sample)
@@ -1494,7 +1666,7 @@ static int intel_pt_process_event(struct perf_session *session,
1494 if (pt->timeless_decoding) { 1666 if (pt->timeless_decoding) {
1495 if (event->header.type == PERF_RECORD_EXIT) { 1667 if (event->header.type == PERF_RECORD_EXIT) {
1496 err = intel_pt_process_timeless_queues(pt, 1668 err = intel_pt_process_timeless_queues(pt,
1497 event->comm.tid, 1669 event->fork.tid,
1498 sample->time); 1670 sample->time);
1499 } 1671 }
1500 } else if (timestamp) { 1672 } else if (timestamp) {
@@ -1515,6 +1687,9 @@ static int intel_pt_process_event(struct perf_session *session,
1515 err = intel_pt_process_switch(pt, sample); 1687 err = intel_pt_process_switch(pt, sample);
1516 else if (event->header.type == PERF_RECORD_ITRACE_START) 1688 else if (event->header.type == PERF_RECORD_ITRACE_START)
1517 err = intel_pt_process_itrace_start(pt, event, sample); 1689 err = intel_pt_process_itrace_start(pt, event, sample);
1690 else if (event->header.type == PERF_RECORD_SWITCH ||
1691 event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)
1692 err = intel_pt_context_switch(pt, event, sample);
1518 1693
1519 intel_pt_log("event %s (%u): cpu %d time %"PRIu64" tsc %#"PRIx64"\n", 1694 intel_pt_log("event %s (%u): cpu %d time %"PRIu64" tsc %#"PRIx64"\n",
1520 perf_event__name(event->header.type), event->header.type, 1695 perf_event__name(event->header.type), event->header.type,
@@ -1700,6 +1875,8 @@ static int intel_pt_synth_events(struct intel_pt *pt,
1700 pt->instructions_sample_period = attr.sample_period; 1875 pt->instructions_sample_period = attr.sample_period;
1701 if (pt->synth_opts.callchain) 1876 if (pt->synth_opts.callchain)
1702 attr.sample_type |= PERF_SAMPLE_CALLCHAIN; 1877 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
1878 if (pt->synth_opts.last_branch)
1879 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
1703 pr_debug("Synthesizing 'instructions' event with id %" PRIu64 " sample type %#" PRIx64 "\n", 1880 pr_debug("Synthesizing 'instructions' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
1704 id, (u64)attr.sample_type); 1881 id, (u64)attr.sample_type);
1705 err = intel_pt_synth_event(session, &attr, id); 1882 err = intel_pt_synth_event(session, &attr, id);
@@ -1719,6 +1896,8 @@ static int intel_pt_synth_events(struct intel_pt *pt,
1719 attr.sample_period = 1; 1896 attr.sample_period = 1;
1720 if (pt->synth_opts.callchain) 1897 if (pt->synth_opts.callchain)
1721 attr.sample_type |= PERF_SAMPLE_CALLCHAIN; 1898 attr.sample_type |= PERF_SAMPLE_CALLCHAIN;
1899 if (pt->synth_opts.last_branch)
1900 attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
1722 pr_debug("Synthesizing 'transactions' event with id %" PRIu64 " sample type %#" PRIx64 "\n", 1901 pr_debug("Synthesizing 'transactions' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
1723 id, (u64)attr.sample_type); 1902 id, (u64)attr.sample_type);
1724 err = intel_pt_synth_event(session, &attr, id); 1903 err = intel_pt_synth_event(session, &attr, id);
@@ -1745,6 +1924,7 @@ static int intel_pt_synth_events(struct intel_pt *pt,
1745 attr.sample_period = 1; 1924 attr.sample_period = 1;
1746 attr.sample_type |= PERF_SAMPLE_ADDR; 1925 attr.sample_type |= PERF_SAMPLE_ADDR;
1747 attr.sample_type &= ~(u64)PERF_SAMPLE_CALLCHAIN; 1926 attr.sample_type &= ~(u64)PERF_SAMPLE_CALLCHAIN;
1927 attr.sample_type &= ~(u64)PERF_SAMPLE_BRANCH_STACK;
1748 pr_debug("Synthesizing 'branches' event with id %" PRIu64 " sample type %#" PRIx64 "\n", 1928 pr_debug("Synthesizing 'branches' event with id %" PRIu64 " sample type %#" PRIx64 "\n",
1749 id, (u64)attr.sample_type); 1929 id, (u64)attr.sample_type);
1750 err = intel_pt_synth_event(session, &attr, id); 1930 err = intel_pt_synth_event(session, &attr, id);
@@ -1777,6 +1957,28 @@ static struct perf_evsel *intel_pt_find_sched_switch(struct perf_evlist *evlist)
1777 return NULL; 1957 return NULL;
1778} 1958}
1779 1959
1960static bool intel_pt_find_switch(struct perf_evlist *evlist)
1961{
1962 struct perf_evsel *evsel;
1963
1964 evlist__for_each(evlist, evsel) {
1965 if (evsel->attr.context_switch)
1966 return true;
1967 }
1968
1969 return false;
1970}
1971
1972static int intel_pt_perf_config(const char *var, const char *value, void *data)
1973{
1974 struct intel_pt *pt = data;
1975
1976 if (!strcmp(var, "intel-pt.mispred-all"))
1977 pt->mispred_all = perf_config_bool(var, value);
1978
1979 return 0;
1980}
1981
1780static const char * const intel_pt_info_fmts[] = { 1982static const char * const intel_pt_info_fmts[] = {
1781 [INTEL_PT_PMU_TYPE] = " PMU Type %"PRId64"\n", 1983 [INTEL_PT_PMU_TYPE] = " PMU Type %"PRId64"\n",
1782 [INTEL_PT_TIME_SHIFT] = " Time Shift %"PRIu64"\n", 1984 [INTEL_PT_TIME_SHIFT] = " Time Shift %"PRIu64"\n",
@@ -1821,6 +2023,8 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
1821 if (!pt) 2023 if (!pt)
1822 return -ENOMEM; 2024 return -ENOMEM;
1823 2025
2026 perf_config(intel_pt_perf_config, pt);
2027
1824 err = auxtrace_queues__init(&pt->queues); 2028 err = auxtrace_queues__init(&pt->queues);
1825 if (err) 2029 if (err)
1826 goto err_free; 2030 goto err_free;
@@ -1888,6 +2092,10 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
1888 pr_err("%s: missing sched_switch event\n", __func__); 2092 pr_err("%s: missing sched_switch event\n", __func__);
1889 goto err_delete_thread; 2093 goto err_delete_thread;
1890 } 2094 }
2095 } else if (pt->have_sched_switch == 2 &&
2096 !intel_pt_find_switch(session->evlist)) {
2097 pr_err("%s: missing context_switch attribute flag\n", __func__);
2098 goto err_delete_thread;
1891 } 2099 }
1892 2100
1893 if (session->itrace_synth_opts && session->itrace_synth_opts->set) { 2101 if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 6309f7ceb08f..5ef90be2a249 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -35,6 +35,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
35 machine->last_match = NULL; 35 machine->last_match = NULL;
36 36
37 machine->vdso_info = NULL; 37 machine->vdso_info = NULL;
38 machine->env = NULL;
38 39
39 machine->pid = pid; 40 machine->pid = pid;
40 41
@@ -624,7 +625,7 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp)
624{ 625{
625 int i; 626 int i;
626 size_t printed = 0; 627 size_t printed = 0;
627 struct dso *kdso = machine->vmlinux_maps[MAP__FUNCTION]->dso; 628 struct dso *kdso = machine__kernel_map(machine)->dso;
628 629
629 if (kdso->has_build_id) { 630 if (kdso->has_build_id) {
630 char filename[PATH_MAX]; 631 char filename[PATH_MAX];
@@ -740,6 +741,7 @@ int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
740 741
741 for (type = 0; type < MAP__NR_TYPES; ++type) { 742 for (type = 0; type < MAP__NR_TYPES; ++type) {
742 struct kmap *kmap; 743 struct kmap *kmap;
744 struct map *map;
743 745
744 machine->vmlinux_maps[type] = map__new2(start, kernel, type); 746 machine->vmlinux_maps[type] = map__new2(start, kernel, type);
745 if (machine->vmlinux_maps[type] == NULL) 747 if (machine->vmlinux_maps[type] == NULL)
@@ -748,13 +750,13 @@ int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
748 machine->vmlinux_maps[type]->map_ip = 750 machine->vmlinux_maps[type]->map_ip =
749 machine->vmlinux_maps[type]->unmap_ip = 751 machine->vmlinux_maps[type]->unmap_ip =
750 identity__map_ip; 752 identity__map_ip;
751 kmap = map__kmap(machine->vmlinux_maps[type]); 753 map = __machine__kernel_map(machine, type);
754 kmap = map__kmap(map);
752 if (!kmap) 755 if (!kmap)
753 return -1; 756 return -1;
754 757
755 kmap->kmaps = &machine->kmaps; 758 kmap->kmaps = &machine->kmaps;
756 map_groups__insert(&machine->kmaps, 759 map_groups__insert(&machine->kmaps, map);
757 machine->vmlinux_maps[type]);
758 } 760 }
759 761
760 return 0; 762 return 0;
@@ -766,13 +768,13 @@ void machine__destroy_kernel_maps(struct machine *machine)
766 768
767 for (type = 0; type < MAP__NR_TYPES; ++type) { 769 for (type = 0; type < MAP__NR_TYPES; ++type) {
768 struct kmap *kmap; 770 struct kmap *kmap;
771 struct map *map = __machine__kernel_map(machine, type);
769 772
770 if (machine->vmlinux_maps[type] == NULL) 773 if (map == NULL)
771 continue; 774 continue;
772 775
773 kmap = map__kmap(machine->vmlinux_maps[type]); 776 kmap = map__kmap(map);
774 map_groups__remove(&machine->kmaps, 777 map_groups__remove(&machine->kmaps, map);
775 machine->vmlinux_maps[type]);
776 if (kmap && kmap->ref_reloc_sym) { 778 if (kmap && kmap->ref_reloc_sym) {
777 /* 779 /*
778 * ref_reloc_sym is shared among all maps, so free just 780 * ref_reloc_sym is shared among all maps, so free just
@@ -866,7 +868,7 @@ int machines__create_kernel_maps(struct machines *machines, pid_t pid)
866int machine__load_kallsyms(struct machine *machine, const char *filename, 868int machine__load_kallsyms(struct machine *machine, const char *filename,
867 enum map_type type, symbol_filter_t filter) 869 enum map_type type, symbol_filter_t filter)
868{ 870{
869 struct map *map = machine->vmlinux_maps[type]; 871 struct map *map = machine__kernel_map(machine);
870 int ret = dso__load_kallsyms(map->dso, filename, map, filter); 872 int ret = dso__load_kallsyms(map->dso, filename, map, filter);
871 873
872 if (ret > 0) { 874 if (ret > 0) {
@@ -885,7 +887,7 @@ int machine__load_kallsyms(struct machine *machine, const char *filename,
885int machine__load_vmlinux_path(struct machine *machine, enum map_type type, 887int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
886 symbol_filter_t filter) 888 symbol_filter_t filter)
887{ 889{
888 struct map *map = machine->vmlinux_maps[type]; 890 struct map *map = machine__kernel_map(machine);
889 int ret = dso__load_vmlinux_path(map->dso, map, filter); 891 int ret = dso__load_vmlinux_path(map->dso, map, filter);
890 892
891 if (ret > 0) 893 if (ret > 0)
@@ -1243,8 +1245,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
1243 /* 1245 /*
1244 * preload dso of guest kernel and modules 1246 * preload dso of guest kernel and modules
1245 */ 1247 */
1246 dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION], 1248 dso__load(kernel, machine__kernel_map(machine), NULL);
1247 NULL);
1248 } 1249 }
1249 } 1250 }
1250 return 0; 1251 return 0;
@@ -1830,7 +1831,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1830 } 1831 }
1831 1832
1832check_calls: 1833check_calls:
1833 if (chain->nr > PERF_MAX_STACK_DEPTH) { 1834 if (chain->nr > PERF_MAX_STACK_DEPTH && (int)chain->nr > max_stack) {
1834 pr_warning("corrupted callchain. skipping...\n"); 1835 pr_warning("corrupted callchain. skipping...\n");
1835 return 0; 1836 return 0;
1836 } 1837 }
@@ -1996,7 +1997,7 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,
1996 1997
1997int machine__get_kernel_start(struct machine *machine) 1998int machine__get_kernel_start(struct machine *machine)
1998{ 1999{
1999 struct map *map = machine__kernel_map(machine, MAP__FUNCTION); 2000 struct map *map = machine__kernel_map(machine);
2000 int err = 0; 2001 int err = 0;
2001 2002
2002 /* 2003 /*
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index ea5cb4a621db..2c2b443df5ba 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -34,6 +34,7 @@ struct machine {
34 struct list_head dead_threads; 34 struct list_head dead_threads;
35 struct thread *last_match; 35 struct thread *last_match;
36 struct vdso_info *vdso_info; 36 struct vdso_info *vdso_info;
37 struct perf_env *env;
37 struct dsos dsos; 38 struct dsos dsos;
38 struct map_groups kmaps; 39 struct map_groups kmaps;
39 struct map *vmlinux_maps[MAP__NR_TYPES]; 40 struct map *vmlinux_maps[MAP__NR_TYPES];
@@ -47,11 +48,17 @@ struct machine {
47}; 48};
48 49
49static inline 50static inline
50struct map *machine__kernel_map(struct machine *machine, enum map_type type) 51struct map *__machine__kernel_map(struct machine *machine, enum map_type type)
51{ 52{
52 return machine->vmlinux_maps[type]; 53 return machine->vmlinux_maps[type];
53} 54}
54 55
56static inline
57struct map *machine__kernel_map(struct machine *machine)
58{
59 return __machine__kernel_map(machine, MAP__FUNCTION);
60}
61
55int machine__get_kernel_start(struct machine *machine); 62int machine__get_kernel_start(struct machine *machine);
56 63
57static inline u64 machine__kernel_start(struct machine *machine) 64static inline u64 machine__kernel_start(struct machine *machine)
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index b1c475d9b240..4e38c396a897 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -235,7 +235,7 @@ struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
235 */ 235 */
236bool __map__is_kernel(const struct map *map) 236bool __map__is_kernel(const struct map *map)
237{ 237{
238 return map->groups->machine->vmlinux_maps[map->type] == map; 238 return __machine__kernel_map(map->groups->machine, map->type) == map;
239} 239}
240 240
241static void map__exit(struct map *map) 241static void map__exit(struct map *map)
@@ -553,13 +553,9 @@ struct symbol *map_groups__find_symbol(struct map_groups *mg,
553 return NULL; 553 return NULL;
554} 554}
555 555
556struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, 556struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
557 enum map_type type, 557 struct map **mapp, symbol_filter_t filter)
558 const char *name,
559 struct map **mapp,
560 symbol_filter_t filter)
561{ 558{
562 struct maps *maps = &mg->maps[type];
563 struct symbol *sym; 559 struct symbol *sym;
564 struct rb_node *nd; 560 struct rb_node *nd;
565 561
@@ -583,6 +579,17 @@ out:
583 return sym; 579 return sym;
584} 580}
585 581
582struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
583 enum map_type type,
584 const char *name,
585 struct map **mapp,
586 symbol_filter_t filter)
587{
588 struct symbol *sym = maps__find_symbol_by_name(&mg->maps[type], name, mapp, filter);
589
590 return sym;
591}
592
586int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter) 593int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter)
587{ 594{
588 if (ams->addr < ams->map->start || ams->addr >= ams->map->end) { 595 if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 57829e89b78b..7309d64ce39e 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -190,6 +190,8 @@ void maps__remove(struct maps *maps, struct map *map);
190struct map *maps__find(struct maps *maps, u64 addr); 190struct map *maps__find(struct maps *maps, u64 addr);
191struct map *maps__first(struct maps *maps); 191struct map *maps__first(struct maps *maps);
192struct map *map__next(struct map *map); 192struct map *map__next(struct map *map);
193struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
194 struct map **mapp, symbol_filter_t filter);
193void map_groups__init(struct map_groups *mg, struct machine *machine); 195void map_groups__init(struct map_groups *mg, struct machine *machine);
194void map_groups__exit(struct map_groups *mg); 196void map_groups__exit(struct map_groups *mg);
195int map_groups__clone(struct map_groups *mg, 197int map_groups__clone(struct map_groups *mg,
diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
index a3b1e13a05c0..355eecf6bf59 100644
--- a/tools/perf/util/parse-branch-options.c
+++ b/tools/perf/util/parse-branch-options.c
@@ -27,6 +27,7 @@ static const struct branch_mode branch_modes[] = {
27 BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX), 27 BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX),
28 BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND), 28 BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND),
29 BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP), 29 BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP),
30 BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL),
30 BRANCH_END 31 BRANCH_END
31}; 32};
32 33
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d826e6f515db..bee60583839a 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,4 +1,5 @@
1#include <linux/hw_breakpoint.h> 1#include <linux/hw_breakpoint.h>
2#include <linux/err.h>
2#include "util.h" 3#include "util.h"
3#include "../perf.h" 4#include "../perf.h"
4#include "evlist.h" 5#include "evlist.h"
@@ -10,8 +11,9 @@
10#include "symbol.h" 11#include "symbol.h"
11#include "cache.h" 12#include "cache.h"
12#include "header.h" 13#include "header.h"
14#include "bpf-loader.h"
13#include "debug.h" 15#include "debug.h"
14#include <api/fs/debugfs.h> 16#include <api/fs/tracing_path.h>
15#include "parse-events-bison.h" 17#include "parse-events-bison.h"
16#define YY_EXTRA_TYPE int 18#define YY_EXTRA_TYPE int
17#include "parse-events-flex.h" 19#include "parse-events-flex.h"
@@ -26,6 +28,8 @@
26extern int parse_events_debug; 28extern int parse_events_debug;
27#endif 29#endif
28int parse_events_parse(void *data, void *scanner); 30int parse_events_parse(void *data, void *scanner);
31static int get_config_terms(struct list_head *head_config,
32 struct list_head *head_terms __maybe_unused);
29 33
30static struct perf_pmu_event_symbol *perf_pmu_events_list; 34static struct perf_pmu_event_symbol *perf_pmu_events_list;
31/* 35/*
@@ -287,8 +291,8 @@ __add_event(struct list_head *list, int *idx,
287 if (!evsel) 291 if (!evsel)
288 return NULL; 292 return NULL;
289 293
290 if (cpus) 294 evsel->cpus = cpu_map__get(cpus);
291 evsel->cpus = cpu_map__get(cpus); 295 evsel->own_cpus = cpu_map__get(cpus);
292 296
293 if (name) 297 if (name)
294 evsel->name = strdup(name); 298 evsel->name = strdup(name);
@@ -386,32 +390,72 @@ int parse_events_add_cache(struct list_head *list, int *idx,
386 return add_event(list, idx, &attr, name, NULL); 390 return add_event(list, idx, &attr, name, NULL);
387} 391}
388 392
393static void tracepoint_error(struct parse_events_error *e, int err,
394 char *sys, char *name)
395{
396 char help[BUFSIZ];
397
398 /*
399 * We get error directly from syscall errno ( > 0),
400 * or from encoded pointer's error ( < 0).
401 */
402 err = abs(err);
403
404 switch (err) {
405 case EACCES:
406 e->str = strdup("can't access trace events");
407 break;
408 case ENOENT:
409 e->str = strdup("unknown tracepoint");
410 break;
411 default:
412 e->str = strdup("failed to add tracepoint");
413 break;
414 }
415
416 tracing_path__strerror_open_tp(err, help, sizeof(help), sys, name);
417 e->help = strdup(help);
418}
419
389static int add_tracepoint(struct list_head *list, int *idx, 420static int add_tracepoint(struct list_head *list, int *idx,
390 char *sys_name, char *evt_name) 421 char *sys_name, char *evt_name,
422 struct parse_events_error *err,
423 struct list_head *head_config)
391{ 424{
392 struct perf_evsel *evsel; 425 struct perf_evsel *evsel;
393 426
394 evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++); 427 evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++);
395 if (!evsel) 428 if (IS_ERR(evsel)) {
396 return -ENOMEM; 429 tracepoint_error(err, PTR_ERR(evsel), sys_name, evt_name);
430 return PTR_ERR(evsel);
431 }
397 432
398 list_add_tail(&evsel->node, list); 433 if (head_config) {
434 LIST_HEAD(config_terms);
399 435
436 if (get_config_terms(head_config, &config_terms))
437 return -ENOMEM;
438 list_splice(&config_terms, &evsel->config_terms);
439 }
440
441 list_add_tail(&evsel->node, list);
400 return 0; 442 return 0;
401} 443}
402 444
403static int add_tracepoint_multi_event(struct list_head *list, int *idx, 445static int add_tracepoint_multi_event(struct list_head *list, int *idx,
404 char *sys_name, char *evt_name) 446 char *sys_name, char *evt_name,
447 struct parse_events_error *err,
448 struct list_head *head_config)
405{ 449{
406 char evt_path[MAXPATHLEN]; 450 char evt_path[MAXPATHLEN];
407 struct dirent *evt_ent; 451 struct dirent *evt_ent;
408 DIR *evt_dir; 452 DIR *evt_dir;
409 int ret = 0; 453 int ret = 0, found = 0;
410 454
411 snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); 455 snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name);
412 evt_dir = opendir(evt_path); 456 evt_dir = opendir(evt_path);
413 if (!evt_dir) { 457 if (!evt_dir) {
414 perror("Can't open event dir"); 458 tracepoint_error(err, errno, sys_name, evt_name);
415 return -1; 459 return -1;
416 } 460 }
417 461
@@ -425,7 +469,15 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
425 if (!strglobmatch(evt_ent->d_name, evt_name)) 469 if (!strglobmatch(evt_ent->d_name, evt_name))
426 continue; 470 continue;
427 471
428 ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); 472 found++;
473
474 ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name,
475 err, head_config);
476 }
477
478 if (!found) {
479 tracepoint_error(err, ENOENT, sys_name, evt_name);
480 ret = -1;
429 } 481 }
430 482
431 closedir(evt_dir); 483 closedir(evt_dir);
@@ -433,15 +485,21 @@ static int add_tracepoint_multi_event(struct list_head *list, int *idx,
433} 485}
434 486
435static int add_tracepoint_event(struct list_head *list, int *idx, 487static int add_tracepoint_event(struct list_head *list, int *idx,
436 char *sys_name, char *evt_name) 488 char *sys_name, char *evt_name,
489 struct parse_events_error *err,
490 struct list_head *head_config)
437{ 491{
438 return strpbrk(evt_name, "*?") ? 492 return strpbrk(evt_name, "*?") ?
439 add_tracepoint_multi_event(list, idx, sys_name, evt_name) : 493 add_tracepoint_multi_event(list, idx, sys_name, evt_name,
440 add_tracepoint(list, idx, sys_name, evt_name); 494 err, head_config) :
495 add_tracepoint(list, idx, sys_name, evt_name,
496 err, head_config);
441} 497}
442 498
443static int add_tracepoint_multi_sys(struct list_head *list, int *idx, 499static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
444 char *sys_name, char *evt_name) 500 char *sys_name, char *evt_name,
501 struct parse_events_error *err,
502 struct list_head *head_config)
445{ 503{
446 struct dirent *events_ent; 504 struct dirent *events_ent;
447 DIR *events_dir; 505 DIR *events_dir;
@@ -449,7 +507,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
449 507
450 events_dir = opendir(tracing_events_path); 508 events_dir = opendir(tracing_events_path);
451 if (!events_dir) { 509 if (!events_dir) {
452 perror("Can't open event dir"); 510 tracepoint_error(err, errno, sys_name, evt_name);
453 return -1; 511 return -1;
454 } 512 }
455 513
@@ -465,20 +523,135 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
465 continue; 523 continue;
466 524
467 ret = add_tracepoint_event(list, idx, events_ent->d_name, 525 ret = add_tracepoint_event(list, idx, events_ent->d_name,
468 evt_name); 526 evt_name, err, head_config);
469 } 527 }
470 528
471 closedir(events_dir); 529 closedir(events_dir);
472 return ret; 530 return ret;
473} 531}
474 532
475int parse_events_add_tracepoint(struct list_head *list, int *idx, 533struct __add_bpf_event_param {
476 char *sys, char *event) 534 struct parse_events_evlist *data;
535 struct list_head *list;
536};
537
538static int add_bpf_event(struct probe_trace_event *tev, int fd,
539 void *_param)
477{ 540{
478 if (strpbrk(sys, "*?")) 541 LIST_HEAD(new_evsels);
479 return add_tracepoint_multi_sys(list, idx, sys, event); 542 struct __add_bpf_event_param *param = _param;
480 else 543 struct parse_events_evlist *evlist = param->data;
481 return add_tracepoint_event(list, idx, sys, event); 544 struct list_head *list = param->list;
545 struct perf_evsel *pos;
546 int err;
547
548 pr_debug("add bpf event %s:%s and attach bpf program %d\n",
549 tev->group, tev->event, fd);
550
551 err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, tev->group,
552 tev->event, evlist->error, NULL);
553 if (err) {
554 struct perf_evsel *evsel, *tmp;
555
556 pr_debug("Failed to add BPF event %s:%s\n",
557 tev->group, tev->event);
558 list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
559 list_del(&evsel->node);
560 perf_evsel__delete(evsel);
561 }
562 return err;
563 }
564 pr_debug("adding %s:%s\n", tev->group, tev->event);
565
566 list_for_each_entry(pos, &new_evsels, node) {
567 pr_debug("adding %s:%s to %p\n",
568 tev->group, tev->event, pos);
569 pos->bpf_fd = fd;
570 }
571 list_splice(&new_evsels, list);
572 return 0;
573}
574
575int parse_events_load_bpf_obj(struct parse_events_evlist *data,
576 struct list_head *list,
577 struct bpf_object *obj)
578{
579 int err;
580 char errbuf[BUFSIZ];
581 struct __add_bpf_event_param param = {data, list};
582 static bool registered_unprobe_atexit = false;
583
584 if (IS_ERR(obj) || !obj) {
585 snprintf(errbuf, sizeof(errbuf),
586 "Internal error: load bpf obj with NULL");
587 err = -EINVAL;
588 goto errout;
589 }
590
591 /*
592 * Register atexit handler before calling bpf__probe() so
593 * bpf__probe() don't need to unprobe probe points its already
594 * created when failure.
595 */
596 if (!registered_unprobe_atexit) {
597 atexit(bpf__clear);
598 registered_unprobe_atexit = true;
599 }
600
601 err = bpf__probe(obj);
602 if (err) {
603 bpf__strerror_probe(obj, err, errbuf, sizeof(errbuf));
604 goto errout;
605 }
606
607 err = bpf__load(obj);
608 if (err) {
609 bpf__strerror_load(obj, err, errbuf, sizeof(errbuf));
610 goto errout;
611 }
612
613 err = bpf__foreach_tev(obj, add_bpf_event, &param);
614 if (err) {
615 snprintf(errbuf, sizeof(errbuf),
616 "Attach events in BPF object failed");
617 goto errout;
618 }
619
620 return 0;
621errout:
622 data->error->help = strdup("(add -v to see detail)");
623 data->error->str = strdup(errbuf);
624 return err;
625}
626
627int parse_events_load_bpf(struct parse_events_evlist *data,
628 struct list_head *list,
629 char *bpf_file_name,
630 bool source)
631{
632 struct bpf_object *obj;
633
634 obj = bpf__prepare_load(bpf_file_name, source);
635 if (IS_ERR(obj) || !obj) {
636 char errbuf[BUFSIZ];
637 int err;
638
639 err = obj ? PTR_ERR(obj) : -EINVAL;
640
641 if (err == -ENOTSUP)
642 snprintf(errbuf, sizeof(errbuf),
643 "BPF support is not compiled");
644 else
645 snprintf(errbuf, sizeof(errbuf),
646 "BPF object file '%s' is invalid",
647 bpf_file_name);
648
649 data->error->help = strdup("(add -v to see detail)");
650 data->error->str = strdup(errbuf);
651 return err;
652 }
653
654 return parse_events_load_bpf_obj(data, list, obj);
482} 655}
483 656
484static int 657static int
@@ -565,9 +738,13 @@ static int check_type_val(struct parse_events_term *term,
565 return -EINVAL; 738 return -EINVAL;
566} 739}
567 740
568static int config_term(struct perf_event_attr *attr, 741typedef int config_term_func_t(struct perf_event_attr *attr,
569 struct parse_events_term *term, 742 struct parse_events_term *term,
570 struct parse_events_error *err) 743 struct parse_events_error *err);
744
745static int config_term_common(struct perf_event_attr *attr,
746 struct parse_events_term *term,
747 struct parse_events_error *err)
571{ 748{
572#define CHECK_TYPE_VAL(type) \ 749#define CHECK_TYPE_VAL(type) \
573do { \ 750do { \
@@ -576,12 +753,6 @@ do { \
576} while (0) 753} while (0)
577 754
578 switch (term->type_term) { 755 switch (term->type_term) {
579 case PARSE_EVENTS__TERM_TYPE_USER:
580 /*
581 * Always succeed for sysfs terms, as we dont know
582 * at this point what type they need to have.
583 */
584 return 0;
585 case PARSE_EVENTS__TERM_TYPE_CONFIG: 756 case PARSE_EVENTS__TERM_TYPE_CONFIG:
586 CHECK_TYPE_VAL(NUM); 757 CHECK_TYPE_VAL(NUM);
587 attr->config = term->val.num; 758 attr->config = term->val.num;
@@ -620,10 +791,19 @@ do { \
620 case PARSE_EVENTS__TERM_TYPE_STACKSIZE: 791 case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
621 CHECK_TYPE_VAL(NUM); 792 CHECK_TYPE_VAL(NUM);
622 break; 793 break;
794 case PARSE_EVENTS__TERM_TYPE_INHERIT:
795 CHECK_TYPE_VAL(NUM);
796 break;
797 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
798 CHECK_TYPE_VAL(NUM);
799 break;
623 case PARSE_EVENTS__TERM_TYPE_NAME: 800 case PARSE_EVENTS__TERM_TYPE_NAME:
624 CHECK_TYPE_VAL(STR); 801 CHECK_TYPE_VAL(STR);
625 break; 802 break;
626 default: 803 default:
804 err->str = strdup("unknown term");
805 err->idx = term->err_term;
806 err->help = parse_events_formats_error_string(NULL);
627 return -EINVAL; 807 return -EINVAL;
628 } 808 }
629 809
@@ -631,9 +811,46 @@ do { \
631#undef CHECK_TYPE_VAL 811#undef CHECK_TYPE_VAL
632} 812}
633 813
814static int config_term_pmu(struct perf_event_attr *attr,
815 struct parse_events_term *term,
816 struct parse_events_error *err)
817{
818 if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER)
819 /*
820 * Always succeed for sysfs terms, as we dont know
821 * at this point what type they need to have.
822 */
823 return 0;
824 else
825 return config_term_common(attr, term, err);
826}
827
828static int config_term_tracepoint(struct perf_event_attr *attr,
829 struct parse_events_term *term,
830 struct parse_events_error *err)
831{
832 switch (term->type_term) {
833 case PARSE_EVENTS__TERM_TYPE_CALLGRAPH:
834 case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
835 case PARSE_EVENTS__TERM_TYPE_INHERIT:
836 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
837 return config_term_common(attr, term, err);
838 default:
839 if (err) {
840 err->idx = term->err_term;
841 err->str = strdup("unknown term");
842 err->help = strdup("valid terms: call-graph,stack-size\n");
843 }
844 return -EINVAL;
845 }
846
847 return 0;
848}
849
634static int config_attr(struct perf_event_attr *attr, 850static int config_attr(struct perf_event_attr *attr,
635 struct list_head *head, 851 struct list_head *head,
636 struct parse_events_error *err) 852 struct parse_events_error *err,
853 config_term_func_t config_term)
637{ 854{
638 struct parse_events_term *term; 855 struct parse_events_term *term;
639 856
@@ -680,6 +897,12 @@ do { \
680 case PARSE_EVENTS__TERM_TYPE_STACKSIZE: 897 case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
681 ADD_CONFIG_TERM(STACK_USER, stack_user, term->val.num); 898 ADD_CONFIG_TERM(STACK_USER, stack_user, term->val.num);
682 break; 899 break;
900 case PARSE_EVENTS__TERM_TYPE_INHERIT:
901 ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 1 : 0);
902 break;
903 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
904 ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 0 : 1);
905 break;
683 default: 906 default:
684 break; 907 break;
685 } 908 }
@@ -688,6 +911,27 @@ do { \
688 return 0; 911 return 0;
689} 912}
690 913
914int parse_events_add_tracepoint(struct list_head *list, int *idx,
915 char *sys, char *event,
916 struct parse_events_error *err,
917 struct list_head *head_config)
918{
919 if (head_config) {
920 struct perf_event_attr attr;
921
922 if (config_attr(&attr, head_config, err,
923 config_term_tracepoint))
924 return -EINVAL;
925 }
926
927 if (strpbrk(sys, "*?"))
928 return add_tracepoint_multi_sys(list, idx, sys, event,
929 err, head_config);
930 else
931 return add_tracepoint_event(list, idx, sys, event,
932 err, head_config);
933}
934
691int parse_events_add_numeric(struct parse_events_evlist *data, 935int parse_events_add_numeric(struct parse_events_evlist *data,
692 struct list_head *list, 936 struct list_head *list,
693 u32 type, u64 config, 937 u32 type, u64 config,
@@ -701,7 +945,8 @@ int parse_events_add_numeric(struct parse_events_evlist *data,
701 attr.config = config; 945 attr.config = config;
702 946
703 if (head_config) { 947 if (head_config) {
704 if (config_attr(&attr, head_config, data->error)) 948 if (config_attr(&attr, head_config, data->error,
949 config_term_common))
705 return -EINVAL; 950 return -EINVAL;
706 951
707 if (get_config_terms(head_config, &config_terms)) 952 if (get_config_terms(head_config, &config_terms))
@@ -761,7 +1006,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
761 * Configure hardcoded terms first, no need to check 1006 * Configure hardcoded terms first, no need to check
762 * return value when called with fail == 0 ;) 1007 * return value when called with fail == 0 ;)
763 */ 1008 */
764 if (config_attr(&attr, head_config, data->error)) 1009 if (config_attr(&attr, head_config, data->error, config_term_pmu))
765 return -EINVAL; 1010 return -EINVAL;
766 1011
767 if (get_config_terms(head_config, &config_terms)) 1012 if (get_config_terms(head_config, &config_terms))
@@ -793,6 +1038,11 @@ void parse_events__set_leader(char *name, struct list_head *list)
793{ 1038{
794 struct perf_evsel *leader; 1039 struct perf_evsel *leader;
795 1040
1041 if (list_empty(list)) {
1042 WARN_ONCE(true, "WARNING: failed to set leader: empty list");
1043 return;
1044 }
1045
796 __perf_evlist__set_leader(list); 1046 __perf_evlist__set_leader(list);
797 leader = list_entry(list->next, struct perf_evsel, node); 1047 leader = list_entry(list->next, struct perf_evsel, node);
798 leader->group_name = name ? strdup(name) : NULL; 1048 leader->group_name = name ? strdup(name) : NULL;
@@ -819,6 +1069,7 @@ struct event_modifier {
819 int eG; 1069 int eG;
820 int eI; 1070 int eI;
821 int precise; 1071 int precise;
1072 int precise_max;
822 int exclude_GH; 1073 int exclude_GH;
823 int sample_read; 1074 int sample_read;
824 int pinned; 1075 int pinned;
@@ -834,6 +1085,7 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
834 int eG = evsel ? evsel->attr.exclude_guest : 0; 1085 int eG = evsel ? evsel->attr.exclude_guest : 0;
835 int eI = evsel ? evsel->attr.exclude_idle : 0; 1086 int eI = evsel ? evsel->attr.exclude_idle : 0;
836 int precise = evsel ? evsel->attr.precise_ip : 0; 1087 int precise = evsel ? evsel->attr.precise_ip : 0;
1088 int precise_max = 0;
837 int sample_read = 0; 1089 int sample_read = 0;
838 int pinned = evsel ? evsel->attr.pinned : 0; 1090 int pinned = evsel ? evsel->attr.pinned : 0;
839 1091
@@ -870,6 +1122,8 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
870 /* use of precise requires exclude_guest */ 1122 /* use of precise requires exclude_guest */
871 if (!exclude_GH) 1123 if (!exclude_GH)
872 eG = 1; 1124 eG = 1;
1125 } else if (*str == 'P') {
1126 precise_max = 1;
873 } else if (*str == 'S') { 1127 } else if (*str == 'S') {
874 sample_read = 1; 1128 sample_read = 1;
875 } else if (*str == 'D') { 1129 } else if (*str == 'D') {
@@ -900,6 +1154,7 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
900 mod->eG = eG; 1154 mod->eG = eG;
901 mod->eI = eI; 1155 mod->eI = eI;
902 mod->precise = precise; 1156 mod->precise = precise;
1157 mod->precise_max = precise_max;
903 mod->exclude_GH = exclude_GH; 1158 mod->exclude_GH = exclude_GH;
904 mod->sample_read = sample_read; 1159 mod->sample_read = sample_read;
905 mod->pinned = pinned; 1160 mod->pinned = pinned;
@@ -916,7 +1171,7 @@ static int check_modifier(char *str)
916 char *p = str; 1171 char *p = str;
917 1172
918 /* The sizeof includes 0 byte as well. */ 1173 /* The sizeof includes 0 byte as well. */
919 if (strlen(str) > (sizeof("ukhGHpppSDI") - 1)) 1174 if (strlen(str) > (sizeof("ukhGHpppPSDI") - 1))
920 return -1; 1175 return -1;
921 1176
922 while (*p) { 1177 while (*p) {
@@ -955,6 +1210,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
955 evsel->attr.exclude_idle = mod.eI; 1210 evsel->attr.exclude_idle = mod.eI;
956 evsel->exclude_GH = mod.exclude_GH; 1211 evsel->exclude_GH = mod.exclude_GH;
957 evsel->sample_read = mod.sample_read; 1212 evsel->sample_read = mod.sample_read;
1213 evsel->precise_max = mod.precise_max;
958 1214
959 if (perf_evsel__is_group_leader(evsel)) 1215 if (perf_evsel__is_group_leader(evsel))
960 evsel->attr.pinned = mod.pinned; 1216 evsel->attr.pinned = mod.pinned;
@@ -1140,10 +1396,14 @@ int parse_events(struct perf_evlist *evlist, const char *str,
1140 ret = parse_events__scanner(str, &data, PE_START_EVENTS); 1396 ret = parse_events__scanner(str, &data, PE_START_EVENTS);
1141 perf_pmu__parse_cleanup(); 1397 perf_pmu__parse_cleanup();
1142 if (!ret) { 1398 if (!ret) {
1143 int entries = data.idx - evlist->nr_entries;
1144 struct perf_evsel *last; 1399 struct perf_evsel *last;
1145 1400
1146 perf_evlist__splice_list_tail(evlist, &data.list, entries); 1401 if (list_empty(&data.list)) {
1402 WARN_ONCE(true, "WARNING: event parser found nothing");
1403 return -1;
1404 }
1405
1406 perf_evlist__splice_list_tail(evlist, &data.list);
1147 evlist->nr_groups += data.nr_groups; 1407 evlist->nr_groups += data.nr_groups;
1148 last = perf_evlist__last(evlist); 1408 last = perf_evlist__last(evlist);
1149 last->cmdline_group_boundary = true; 1409 last->cmdline_group_boundary = true;
@@ -1252,6 +1512,12 @@ foreach_evsel_in_last_glob(struct perf_evlist *evlist,
1252 struct perf_evsel *last = NULL; 1512 struct perf_evsel *last = NULL;
1253 int err; 1513 int err;
1254 1514
1515 /*
1516 * Don't return when list_empty, give func a chance to report
1517 * error when it found last == NULL.
1518 *
1519 * So no need to WARN here, let *func do this.
1520 */
1255 if (evlist->nr_entries > 0) 1521 if (evlist->nr_entries > 0)
1256 last = perf_evlist__last(evlist); 1522 last = perf_evlist__last(evlist);
1257 1523
@@ -1420,7 +1686,7 @@ restart:
1420 printf(" %-50s [%s]\n", evt_list[evt_i++], 1686 printf(" %-50s [%s]\n", evt_list[evt_i++],
1421 event_type_descriptors[PERF_TYPE_TRACEPOINT]); 1687 event_type_descriptors[PERF_TYPE_TRACEPOINT]);
1422 } 1688 }
1423 if (evt_num) 1689 if (evt_num && pager_in_use())
1424 printf("\n"); 1690 printf("\n");
1425 1691
1426out_free: 1692out_free:
@@ -1576,7 +1842,7 @@ restart:
1576 printf(" %-50s [%s]\n", evt_list[evt_i++], 1842 printf(" %-50s [%s]\n", evt_list[evt_i++],
1577 event_type_descriptors[PERF_TYPE_HW_CACHE]); 1843 event_type_descriptors[PERF_TYPE_HW_CACHE]);
1578 } 1844 }
1579 if (evt_num) 1845 if (evt_num && pager_in_use())
1580 printf("\n"); 1846 printf("\n");
1581 1847
1582out_free: 1848out_free:
@@ -1649,7 +1915,7 @@ restart:
1649 } 1915 }
1650 printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); 1916 printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]);
1651 } 1917 }
1652 if (evt_num) 1918 if (evt_num && pager_in_use())
1653 printf("\n"); 1919 printf("\n");
1654 1920
1655out_free: 1921out_free:
@@ -1690,13 +1956,14 @@ void print_events(const char *event_glob, bool name_only)
1690 printf(" %-50s [%s]\n", 1956 printf(" %-50s [%s]\n",
1691 "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 1957 "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
1692 event_type_descriptors[PERF_TYPE_RAW]); 1958 event_type_descriptors[PERF_TYPE_RAW]);
1693 printf(" (see 'man perf-list' on how to encode it)\n"); 1959 if (pager_in_use())
1694 printf("\n"); 1960 printf(" (see 'man perf-list' on how to encode it)\n\n");
1695 1961
1696 printf(" %-50s [%s]\n", 1962 printf(" %-50s [%s]\n",
1697 "mem:<addr>[/len][:access]", 1963 "mem:<addr>[/len][:access]",
1698 event_type_descriptors[PERF_TYPE_BREAKPOINT]); 1964 event_type_descriptors[PERF_TYPE_BREAKPOINT]);
1699 printf("\n"); 1965 if (pager_in_use())
1966 printf("\n");
1700 } 1967 }
1701 1968
1702 print_tracepoint_events(NULL, NULL, name_only); 1969 print_tracepoint_events(NULL, NULL, name_only);
@@ -1812,3 +2079,29 @@ void parse_events_evlist_error(struct parse_events_evlist *data,
1812 err->str = strdup(str); 2079 err->str = strdup(str);
1813 WARN_ONCE(!err->str, "WARNING: failed to allocate error string"); 2080 WARN_ONCE(!err->str, "WARNING: failed to allocate error string");
1814} 2081}
2082
2083/*
2084 * Return string contains valid config terms of an event.
2085 * @additional_terms: For terms such as PMU sysfs terms.
2086 */
2087char *parse_events_formats_error_string(char *additional_terms)
2088{
2089 char *str;
2090 static const char *static_terms = "config,config1,config2,name,"
2091 "period,freq,branch_type,time,"
2092 "call-graph,stack-size\n";
2093
2094 /* valid terms */
2095 if (additional_terms) {
2096 if (!asprintf(&str, "valid terms: %s,%s",
2097 additional_terms, static_terms))
2098 goto fail;
2099 } else {
2100 if (!asprintf(&str, "valid terms: %s", static_terms))
2101 goto fail;
2102 }
2103 return str;
2104
2105fail:
2106 return NULL;
2107}
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index a09b0e210997..f1a6db107241 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -67,6 +67,8 @@ enum {
67 PARSE_EVENTS__TERM_TYPE_TIME, 67 PARSE_EVENTS__TERM_TYPE_TIME,
68 PARSE_EVENTS__TERM_TYPE_CALLGRAPH, 68 PARSE_EVENTS__TERM_TYPE_CALLGRAPH,
69 PARSE_EVENTS__TERM_TYPE_STACKSIZE, 69 PARSE_EVENTS__TERM_TYPE_STACKSIZE,
70 PARSE_EVENTS__TERM_TYPE_NOINHERIT,
71 PARSE_EVENTS__TERM_TYPE_INHERIT
70}; 72};
71 73
72struct parse_events_term { 74struct parse_events_term {
@@ -118,7 +120,18 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add);
118int parse_events__modifier_group(struct list_head *list, char *event_mod); 120int parse_events__modifier_group(struct list_head *list, char *event_mod);
119int parse_events_name(struct list_head *list, char *name); 121int parse_events_name(struct list_head *list, char *name);
120int parse_events_add_tracepoint(struct list_head *list, int *idx, 122int parse_events_add_tracepoint(struct list_head *list, int *idx,
121 char *sys, char *event); 123 char *sys, char *event,
124 struct parse_events_error *error,
125 struct list_head *head_config);
126int parse_events_load_bpf(struct parse_events_evlist *data,
127 struct list_head *list,
128 char *bpf_file_name,
129 bool source);
130/* Provide this function for perf test */
131struct bpf_object;
132int parse_events_load_bpf_obj(struct parse_events_evlist *data,
133 struct list_head *list,
134 struct bpf_object *obj);
122int parse_events_add_numeric(struct parse_events_evlist *data, 135int parse_events_add_numeric(struct parse_events_evlist *data,
123 struct list_head *list, 136 struct list_head *list,
124 u32 type, u64 config, 137 u32 type, u64 config,
@@ -155,5 +168,6 @@ int print_hwcache_events(const char *event_glob, bool name_only);
155extern int is_valid_tracepoint(const char *event_string); 168extern int is_valid_tracepoint(const char *event_string);
156 169
157int valid_event_mount(const char *eventfs); 170int valid_event_mount(const char *eventfs);
171char *parse_events_formats_error_string(char *additional_terms);
158 172
159#endif /* __PERF_PARSE_EVENTS_H */ 173#endif /* __PERF_PARSE_EVENTS_H */
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 936d566f48d8..58c5831ffd5c 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -115,6 +115,8 @@ do { \
115group [^,{}/]*[{][^}]*[}][^,{}/]* 115group [^,{}/]*[{][^}]*[}][^,{}/]*
116event_pmu [^,{}/]+[/][^/]*[/][^,{}/]* 116event_pmu [^,{}/]+[/][^/]*[/][^,{}/]*
117event [^,{}/]+ 117event [^,{}/]+
118bpf_object .*\.(o|bpf)
119bpf_source .*\.c
118 120
119num_dec [0-9]+ 121num_dec [0-9]+
120num_hex 0x[a-fA-F0-9]+ 122num_hex 0x[a-fA-F0-9]+
@@ -122,7 +124,7 @@ num_raw_hex [a-fA-F0-9]+
122name [a-zA-Z_*?][a-zA-Z0-9_*?.]* 124name [a-zA-Z_*?][a-zA-Z0-9_*?.]*
123name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?.]* 125name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?.]*
124/* If you add a modifier you need to update check_modifier() */ 126/* If you add a modifier you need to update check_modifier() */
125modifier_event [ukhpGHSDI]+ 127modifier_event [ukhpPGHSDI]+
126modifier_bp [rwx]{1,3} 128modifier_bp [rwx]{1,3}
127 129
128%% 130%%
@@ -159,6 +161,8 @@ modifier_bp [rwx]{1,3}
159 } 161 }
160 162
161{event_pmu} | 163{event_pmu} |
164{bpf_object} |
165{bpf_source} |
162{event} { 166{event} {
163 BEGIN(INITIAL); 167 BEGIN(INITIAL);
164 REWIND(1); 168 REWIND(1);
@@ -174,7 +178,7 @@ modifier_bp [rwx]{1,3}
174 178
175<config>{ 179<config>{
176 /* 180 /*
177 * Please update formats_error_string any time 181 * Please update parse_events_formats_error_string any time
178 * new static term is added. 182 * new static term is added.
179 */ 183 */
180config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); } 184config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
@@ -187,6 +191,8 @@ branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE
187time { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_TIME); } 191time { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_TIME); }
188call-graph { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CALLGRAPH); } 192call-graph { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CALLGRAPH); }
189stack-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_STACKSIZE); } 193stack-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_STACKSIZE); }
194inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
195no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
190, { return ','; } 196, { return ','; }
191"/" { BEGIN(INITIAL); return '/'; } 197"/" { BEGIN(INITIAL); return '/'; }
192{name_minus} { return str(yyscanner, PE_NAME); } 198{name_minus} { return str(yyscanner, PE_NAME); }
@@ -264,6 +270,8 @@ r{num_raw_hex} { return raw(yyscanner); }
264{num_hex} { return value(yyscanner, 16); } 270{num_hex} { return value(yyscanner, 16); }
265 271
266{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } 272{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
273{bpf_object} { return str(yyscanner, PE_BPF_OBJECT); }
274{bpf_source} { return str(yyscanner, PE_BPF_SOURCE); }
267{name} { return pmu_str_check(yyscanner); } 275{name} { return pmu_str_check(yyscanner); }
268"/" { BEGIN(config); return '/'; } 276"/" { BEGIN(config); return '/'; }
269- { return '-'; } 277- { return '-'; }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 591905a02b92..ad379968d4c1 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -42,6 +42,7 @@ static inc_group_count(struct list_head *list,
42%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM 42%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
43%token PE_EVENT_NAME 43%token PE_EVENT_NAME
44%token PE_NAME 44%token PE_NAME
45%token PE_BPF_OBJECT PE_BPF_SOURCE
45%token PE_MODIFIER_EVENT PE_MODIFIER_BP 46%token PE_MODIFIER_EVENT PE_MODIFIER_BP
46%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 47%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
47%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP 48%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
@@ -53,6 +54,8 @@ static inc_group_count(struct list_head *list,
53%type <num> PE_RAW 54%type <num> PE_RAW
54%type <num> PE_TERM 55%type <num> PE_TERM
55%type <str> PE_NAME 56%type <str> PE_NAME
57%type <str> PE_BPF_OBJECT
58%type <str> PE_BPF_SOURCE
56%type <str> PE_NAME_CACHE_TYPE 59%type <str> PE_NAME_CACHE_TYPE
57%type <str> PE_NAME_CACHE_OP_RESULT 60%type <str> PE_NAME_CACHE_OP_RESULT
58%type <str> PE_MODIFIER_EVENT 61%type <str> PE_MODIFIER_EVENT
@@ -67,8 +70,10 @@ static inc_group_count(struct list_head *list,
67%type <head> event_legacy_cache 70%type <head> event_legacy_cache
68%type <head> event_legacy_mem 71%type <head> event_legacy_mem
69%type <head> event_legacy_tracepoint 72%type <head> event_legacy_tracepoint
73%type <tracepoint_name> tracepoint_name
70%type <head> event_legacy_numeric 74%type <head> event_legacy_numeric
71%type <head> event_legacy_raw 75%type <head> event_legacy_raw
76%type <head> event_bpf_file
72%type <head> event_def 77%type <head> event_def
73%type <head> event_mod 78%type <head> event_mod
74%type <head> event_name 79%type <head> event_name
@@ -84,6 +89,10 @@ static inc_group_count(struct list_head *list,
84 u64 num; 89 u64 num;
85 struct list_head *head; 90 struct list_head *head;
86 struct parse_events_term *term; 91 struct parse_events_term *term;
92 struct tracepoint_name {
93 char *sys;
94 char *event;
95 } tracepoint_name;
87} 96}
88%% 97%%
89 98
@@ -198,7 +207,8 @@ event_def: event_pmu |
198 event_legacy_mem | 207 event_legacy_mem |
199 event_legacy_tracepoint sep_dc | 208 event_legacy_tracepoint sep_dc |
200 event_legacy_numeric sep_dc | 209 event_legacy_numeric sep_dc |
201 event_legacy_raw sep_dc 210 event_legacy_raw sep_dc |
211 event_bpf_file
202 212
203event_pmu: 213event_pmu:
204PE_NAME '/' event_config '/' 214PE_NAME '/' event_config '/'
@@ -255,7 +265,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
255 list_add_tail(&term->list, head); 265 list_add_tail(&term->list, head);
256 266
257 ALLOC_LIST(list); 267 ALLOC_LIST(list);
258 ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); 268 ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
259 parse_events__free_terms(head); 269 parse_events__free_terms(head);
260 $$ = list; 270 $$ = list;
261} 271}
@@ -368,36 +378,60 @@ PE_PREFIX_MEM PE_VALUE sep_dc
368} 378}
369 379
370event_legacy_tracepoint: 380event_legacy_tracepoint:
371PE_NAME '-' PE_NAME ':' PE_NAME 381tracepoint_name
372{ 382{
373 struct parse_events_evlist *data = _data; 383 struct parse_events_evlist *data = _data;
384 struct parse_events_error *error = data->error;
374 struct list_head *list; 385 struct list_head *list;
375 char sys_name[128];
376 snprintf(&sys_name, 128, "%s-%s", $1, $3);
377 386
378 ALLOC_LIST(list); 387 ALLOC_LIST(list);
379 ABORT_ON(parse_events_add_tracepoint(list, &data->idx, &sys_name, $5)); 388 if (error)
389 error->idx = @1.first_column;
390
391 if (parse_events_add_tracepoint(list, &data->idx, $1.sys, $1.event,
392 error, NULL))
393 return -1;
394
380 $$ = list; 395 $$ = list;
381} 396}
382| 397|
383PE_NAME ':' PE_NAME 398tracepoint_name '/' event_config '/'
384{ 399{
385 struct parse_events_evlist *data = _data; 400 struct parse_events_evlist *data = _data;
401 struct parse_events_error *error = data->error;
386 struct list_head *list; 402 struct list_head *list;
387 403
388 ALLOC_LIST(list); 404 ALLOC_LIST(list);
389 if (parse_events_add_tracepoint(list, &data->idx, $1, $3)) { 405 if (error)
390 struct parse_events_error *error = data->error; 406 error->idx = @1.first_column;
391 407
392 if (error) { 408 if (parse_events_add_tracepoint(list, &data->idx, $1.sys, $1.event,
393 error->idx = @1.first_column; 409 error, $3))
394 error->str = strdup("unknown tracepoint");
395 }
396 return -1; 410 return -1;
397 } 411
398 $$ = list; 412 $$ = list;
399} 413}
400 414
415tracepoint_name:
416PE_NAME '-' PE_NAME ':' PE_NAME
417{
418 char sys_name[128];
419 struct tracepoint_name tracepoint;
420
421 snprintf(&sys_name, 128, "%s-%s", $1, $3);
422 tracepoint.sys = &sys_name;
423 tracepoint.event = $5;
424
425 $$ = tracepoint;
426}
427|
428PE_NAME ':' PE_NAME
429{
430 struct tracepoint_name tracepoint = {$1, $3};
431
432 $$ = tracepoint;
433}
434
401event_legacy_numeric: 435event_legacy_numeric:
402PE_VALUE ':' PE_VALUE 436PE_VALUE ':' PE_VALUE
403{ 437{
@@ -420,6 +454,28 @@ PE_RAW
420 $$ = list; 454 $$ = list;
421} 455}
422 456
457event_bpf_file:
458PE_BPF_OBJECT
459{
460 struct parse_events_evlist *data = _data;
461 struct parse_events_error *error = data->error;
462 struct list_head *list;
463
464 ALLOC_LIST(list);
465 ABORT_ON(parse_events_load_bpf(data, list, $1, false));
466 $$ = list;
467}
468|
469PE_BPF_SOURCE
470{
471 struct parse_events_evlist *data = _data;
472 struct list_head *list;
473
474 ALLOC_LIST(list);
475 ABORT_ON(parse_events_load_bpf(data, list, $1, true));
476 $$ = list;
477}
478
423start_terms: event_config 479start_terms: event_config
424{ 480{
425 struct parse_events_terms *data = _data; 481 struct parse_events_terms *data = _data;
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 01626be2a8eb..9fca09296eb3 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -2,10 +2,13 @@
2#include "parse-options.h" 2#include "parse-options.h"
3#include "cache.h" 3#include "cache.h"
4#include "header.h" 4#include "header.h"
5#include <linux/string.h>
5 6
6#define OPT_SHORT 1 7#define OPT_SHORT 1
7#define OPT_UNSET 2 8#define OPT_UNSET 2
8 9
10static struct strbuf error_buf = STRBUF_INIT;
11
9static int opterror(const struct option *opt, const char *reason, int flags) 12static int opterror(const struct option *opt, const char *reason, int flags)
10{ 13{
11 if (flags & OPT_SHORT) 14 if (flags & OPT_SHORT)
@@ -372,7 +375,8 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
372} 375}
373 376
374static int usage_with_options_internal(const char * const *, 377static int usage_with_options_internal(const char * const *,
375 const struct option *, int); 378 const struct option *, int,
379 struct parse_opt_ctx_t *);
376 380
377int parse_options_step(struct parse_opt_ctx_t *ctx, 381int parse_options_step(struct parse_opt_ctx_t *ctx,
378 const struct option *options, 382 const struct option *options,
@@ -396,8 +400,9 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
396 400
397 if (arg[1] != '-') { 401 if (arg[1] != '-') {
398 ctx->opt = ++arg; 402 ctx->opt = ++arg;
399 if (internal_help && *ctx->opt == 'h') 403 if (internal_help && *ctx->opt == 'h') {
400 return usage_with_options_internal(usagestr, options, 0); 404 return usage_with_options_internal(usagestr, options, 0, ctx);
405 }
401 switch (parse_short_opt(ctx, options)) { 406 switch (parse_short_opt(ctx, options)) {
402 case -1: 407 case -1:
403 return parse_options_usage(usagestr, options, arg, 1); 408 return parse_options_usage(usagestr, options, arg, 1);
@@ -412,7 +417,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
412 check_typos(arg, options); 417 check_typos(arg, options);
413 while (ctx->opt) { 418 while (ctx->opt) {
414 if (internal_help && *ctx->opt == 'h') 419 if (internal_help && *ctx->opt == 'h')
415 return usage_with_options_internal(usagestr, options, 0); 420 return usage_with_options_internal(usagestr, options, 0, ctx);
416 arg = ctx->opt; 421 arg = ctx->opt;
417 switch (parse_short_opt(ctx, options)) { 422 switch (parse_short_opt(ctx, options)) {
418 case -1: 423 case -1:
@@ -445,9 +450,9 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
445 450
446 arg += 2; 451 arg += 2;
447 if (internal_help && !strcmp(arg, "help-all")) 452 if (internal_help && !strcmp(arg, "help-all"))
448 return usage_with_options_internal(usagestr, options, 1); 453 return usage_with_options_internal(usagestr, options, 1, ctx);
449 if (internal_help && !strcmp(arg, "help")) 454 if (internal_help && !strcmp(arg, "help"))
450 return usage_with_options_internal(usagestr, options, 0); 455 return usage_with_options_internal(usagestr, options, 0, ctx);
451 if (!strcmp(arg, "list-opts")) 456 if (!strcmp(arg, "list-opts"))
452 return PARSE_OPT_LIST_OPTS; 457 return PARSE_OPT_LIST_OPTS;
453 if (!strcmp(arg, "list-cmds")) 458 if (!strcmp(arg, "list-cmds"))
@@ -496,7 +501,7 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
496{ 501{
497 struct parse_opt_ctx_t ctx; 502 struct parse_opt_ctx_t ctx;
498 503
499 perf_header__set_cmdline(argc, argv); 504 perf_env__set_cmdline(&perf_env, argc, argv);
500 505
501 /* build usage string if it's not provided */ 506 /* build usage string if it's not provided */
502 if (subcommands && !usagestr[0]) { 507 if (subcommands && !usagestr[0]) {
@@ -537,9 +542,11 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
537 exit(130); 542 exit(130);
538 default: /* PARSE_OPT_UNKNOWN */ 543 default: /* PARSE_OPT_UNKNOWN */
539 if (ctx.argv[0][1] == '-') { 544 if (ctx.argv[0][1] == '-') {
540 error("unknown option `%s'", ctx.argv[0] + 2); 545 strbuf_addf(&error_buf, "unknown option `%s'",
546 ctx.argv[0] + 2);
541 } else { 547 } else {
542 error("unknown switch `%c'", *ctx.opt); 548 strbuf_addf(&error_buf, "unknown switch `%c'",
549 *ctx.opt);
543 } 550 }
544 usage_with_options(usagestr, options); 551 usage_with_options(usagestr, options);
545 } 552 }
@@ -642,13 +649,93 @@ static void print_option_help(const struct option *opts, int full)
642 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help); 649 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
643} 650}
644 651
652static int option__cmp(const void *va, const void *vb)
653{
654 const struct option *a = va, *b = vb;
655 int sa = tolower(a->short_name), sb = tolower(b->short_name), ret;
656
657 if (sa == 0)
658 sa = 'z' + 1;
659 if (sb == 0)
660 sb = 'z' + 1;
661
662 ret = sa - sb;
663
664 if (ret == 0) {
665 const char *la = a->long_name ?: "",
666 *lb = b->long_name ?: "";
667 ret = strcmp(la, lb);
668 }
669
670 return ret;
671}
672
673static struct option *options__order(const struct option *opts)
674{
675 int nr_opts = 0;
676 const struct option *o = opts;
677 struct option *ordered;
678
679 for (o = opts; o->type != OPTION_END; o++)
680 ++nr_opts;
681
682 ordered = memdup(opts, sizeof(*o) * (nr_opts + 1));
683 if (ordered == NULL)
684 goto out;
685
686 qsort(ordered, nr_opts, sizeof(*o), option__cmp);
687out:
688 return ordered;
689}
690
691static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx_t *ctx)
692{
693 int i;
694
695 for (i = 1; i < ctx->argc; ++i) {
696 const char *arg = ctx->argv[i];
697
698 if (arg[0] != '-') {
699 if (arg[1] == '\0') {
700 if (arg[0] == opt->short_name)
701 return true;
702 continue;
703 }
704
705 if (opt->long_name && strcmp(opt->long_name, arg) == 0)
706 return true;
707
708 if (opt->help && strcasestr(opt->help, arg) != NULL)
709 return true;
710
711 continue;
712 }
713
714 if (arg[1] == opt->short_name ||
715 (arg[1] == '-' && opt->long_name && strcmp(opt->long_name, arg + 2) == 0))
716 return true;
717 }
718
719 return false;
720}
721
645int usage_with_options_internal(const char * const *usagestr, 722int usage_with_options_internal(const char * const *usagestr,
646 const struct option *opts, int full) 723 const struct option *opts, int full,
724 struct parse_opt_ctx_t *ctx)
647{ 725{
726 struct option *ordered;
727
648 if (!usagestr) 728 if (!usagestr)
649 return PARSE_OPT_HELP; 729 return PARSE_OPT_HELP;
650 730
651 fprintf(stderr, "\n usage: %s\n", *usagestr++); 731 setup_pager();
732
733 if (strbuf_avail(&error_buf)) {
734 fprintf(stderr, " Error: %s\n", error_buf.buf);
735 strbuf_release(&error_buf);
736 }
737
738 fprintf(stderr, "\n Usage: %s\n", *usagestr++);
652 while (*usagestr && **usagestr) 739 while (*usagestr && **usagestr)
653 fprintf(stderr, " or: %s\n", *usagestr++); 740 fprintf(stderr, " or: %s\n", *usagestr++);
654 while (*usagestr) { 741 while (*usagestr) {
@@ -661,11 +748,20 @@ int usage_with_options_internal(const char * const *usagestr,
661 if (opts->type != OPTION_GROUP) 748 if (opts->type != OPTION_GROUP)
662 fputc('\n', stderr); 749 fputc('\n', stderr);
663 750
664 for ( ; opts->type != OPTION_END; opts++) 751 ordered = options__order(opts);
752 if (ordered)
753 opts = ordered;
754
755 for ( ; opts->type != OPTION_END; opts++) {
756 if (ctx && ctx->argc > 1 && !option__in_argv(opts, ctx))
757 continue;
665 print_option_help(opts, full); 758 print_option_help(opts, full);
759 }
666 760
667 fputc('\n', stderr); 761 fputc('\n', stderr);
668 762
763 free(ordered);
764
669 return PARSE_OPT_HELP; 765 return PARSE_OPT_HELP;
670} 766}
671 767
@@ -673,7 +769,22 @@ void usage_with_options(const char * const *usagestr,
673 const struct option *opts) 769 const struct option *opts)
674{ 770{
675 exit_browser(false); 771 exit_browser(false);
676 usage_with_options_internal(usagestr, opts, 0); 772 usage_with_options_internal(usagestr, opts, 0, NULL);
773 exit(129);
774}
775
776void usage_with_options_msg(const char * const *usagestr,
777 const struct option *opts, const char *fmt, ...)
778{
779 va_list ap;
780
781 exit_browser(false);
782
783 va_start(ap, fmt);
784 strbuf_addv(&error_buf, fmt, ap);
785 va_end(ap);
786
787 usage_with_options_internal(usagestr, opts, 0, NULL);
677 exit(129); 788 exit(129);
678} 789}
679 790
@@ -684,7 +795,7 @@ int parse_options_usage(const char * const *usagestr,
684 if (!usagestr) 795 if (!usagestr)
685 goto opt; 796 goto opt;
686 797
687 fprintf(stderr, "\n usage: %s\n", *usagestr++); 798 fprintf(stderr, "\n Usage: %s\n", *usagestr++);
688 while (*usagestr && **usagestr) 799 while (*usagestr && **usagestr)
689 fprintf(stderr, " or: %s\n", *usagestr++); 800 fprintf(stderr, " or: %s\n", *usagestr++);
690 while (*usagestr) { 801 while (*usagestr) {
@@ -698,24 +809,23 @@ int parse_options_usage(const char * const *usagestr,
698opt: 809opt:
699 for ( ; opts->type != OPTION_END; opts++) { 810 for ( ; opts->type != OPTION_END; opts++) {
700 if (short_opt) { 811 if (short_opt) {
701 if (opts->short_name == *optstr) 812 if (opts->short_name == *optstr) {
813 print_option_help(opts, 0);
702 break; 814 break;
815 }
703 continue; 816 continue;
704 } 817 }
705 818
706 if (opts->long_name == NULL) 819 if (opts->long_name == NULL)
707 continue; 820 continue;
708 821
709 if (!prefixcmp(optstr, opts->long_name)) 822 if (!prefixcmp(opts->long_name, optstr))
710 break; 823 print_option_help(opts, 0);
711 if (!prefixcmp(optstr, "no-") && 824 if (!prefixcmp("no-", optstr) &&
712 !prefixcmp(optstr + 3, opts->long_name)) 825 !prefixcmp(opts->long_name, optstr + 3))
713 break; 826 print_option_help(opts, 0);
714 } 827 }
715 828
716 if (opts->type != OPTION_END)
717 print_option_help(opts, 0);
718
719 return PARSE_OPT_HELP; 829 return PARSE_OPT_HELP;
720} 830}
721 831
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index 367d8b816cc7..a8e407bc251e 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -111,6 +111,7 @@ struct option {
111#define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) } 111#define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) }
112#define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) } 112#define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) }
113#define OPT_BOOLEAN(s, l, v, h) { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h) } 113#define OPT_BOOLEAN(s, l, v, h) { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h) }
114#define OPT_BOOLEAN_FLAG(s, l, v, h, f) { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h), .flags = (f) }
114#define OPT_BOOLEAN_SET(s, l, v, os, h) \ 115#define OPT_BOOLEAN_SET(s, l, v, os, h) \
115 { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), \ 116 { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), \
116 .value = check_vtype(v, bool *), .help = (h), \ 117 .value = check_vtype(v, bool *), .help = (h), \
@@ -160,6 +161,10 @@ extern int parse_options_subcommand(int argc, const char **argv,
160 161
161extern NORETURN void usage_with_options(const char * const *usagestr, 162extern NORETURN void usage_with_options(const char * const *usagestr,
162 const struct option *options); 163 const struct option *options);
164extern NORETURN __attribute__((format(printf,3,4)))
165void usage_with_options_msg(const char * const *usagestr,
166 const struct option *options,
167 const char *fmt, ...);
163 168
164/*----- incremantal advanced APIs -----*/ 169/*----- incremantal advanced APIs -----*/
165 170
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
index 885e8ac83997..6b8eb13e14e4 100644
--- a/tools/perf/util/perf_regs.c
+++ b/tools/perf/util/perf_regs.c
@@ -6,6 +6,7 @@ const struct sample_reg __weak sample_reg_masks[] = {
6 SMPL_REG_END 6 SMPL_REG_END
7}; 7};
8 8
9#ifdef HAVE_PERF_REGS_SUPPORT
9int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) 10int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
10{ 11{
11 int i, idx = 0; 12 int i, idx = 0;
@@ -29,3 +30,4 @@ out:
29 *valp = regs->cache_regs[id]; 30 *valp = regs->cache_regs[id];
30 return 0; 31 return 0;
31} 32}
33#endif
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index 2984dcc54d67..679d6e493962 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -2,6 +2,7 @@
2#define __PERF_REGS_H 2#define __PERF_REGS_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/compiler.h>
5 6
6struct regs_dump; 7struct regs_dump;
7 8
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 89c91a1a67e7..e4b173dec4b9 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -626,38 +626,26 @@ static int pmu_resolve_param_term(struct parse_events_term *term,
626 return -1; 626 return -1;
627} 627}
628 628
629static char *formats_error_string(struct list_head *formats) 629static char *pmu_formats_string(struct list_head *formats)
630{ 630{
631 struct perf_pmu_format *format; 631 struct perf_pmu_format *format;
632 char *err, *str; 632 char *str;
633 static const char *static_terms = "config,config1,config2,name," 633 struct strbuf buf;
634 "period,freq,branch_type,time,"
635 "call-graph,stack-size\n";
636 unsigned i = 0; 634 unsigned i = 0;
637 635
638 if (!asprintf(&str, "valid terms:")) 636 if (!formats)
639 return NULL; 637 return NULL;
640 638
639 strbuf_init(&buf, 0);
641 /* sysfs exported terms */ 640 /* sysfs exported terms */
642 list_for_each_entry(format, formats, list) { 641 list_for_each_entry(format, formats, list)
643 char c = i++ ? ',' : ' '; 642 strbuf_addf(&buf, i++ ? ",%s" : "%s",
644 643 format->name);
645 err = str;
646 if (!asprintf(&str, "%s%c%s", err, c, format->name))
647 goto fail;
648 free(err);
649 }
650 644
651 /* static terms */ 645 str = strbuf_detach(&buf, NULL);
652 err = str; 646 strbuf_release(&buf);
653 if (!asprintf(&str, "%s,%s", err, static_terms))
654 goto fail;
655 647
656 free(err);
657 return str; 648 return str;
658fail:
659 free(err);
660 return NULL;
661} 649}
662 650
663/* 651/*
@@ -693,9 +681,12 @@ static int pmu_config_term(struct list_head *formats,
693 if (verbose) 681 if (verbose)
694 printf("Invalid event/parameter '%s'\n", term->config); 682 printf("Invalid event/parameter '%s'\n", term->config);
695 if (err) { 683 if (err) {
684 char *pmu_term = pmu_formats_string(formats);
685
696 err->idx = term->err_term; 686 err->idx = term->err_term;
697 err->str = strdup("unknown term"); 687 err->str = strdup("unknown term");
698 err->help = formats_error_string(formats); 688 err->help = parse_events_formats_error_string(pmu_term);
689 free(pmu_term);
699 } 690 }
700 return -EINVAL; 691 return -EINVAL;
701 } 692 }
@@ -1017,7 +1008,8 @@ void print_pmu_events(const char *event_glob, bool name_only)
1017 goto out_enomem; 1008 goto out_enomem;
1018 j++; 1009 j++;
1019 } 1010 }
1020 if (pmu->selectable) { 1011 if (pmu->selectable &&
1012 (event_glob == NULL || strglobmatch(pmu->name, event_glob))) {
1021 char *s; 1013 char *s;
1022 if (asprintf(&s, "%s//", pmu->name) < 0) 1014 if (asprintf(&s, "%s//", pmu->name) < 0)
1023 goto out_enomem; 1015 goto out_enomem;
@@ -1035,7 +1027,7 @@ void print_pmu_events(const char *event_glob, bool name_only)
1035 printf(" %-50s [Kernel PMU event]\n", aliases[j]); 1027 printf(" %-50s [Kernel PMU event]\n", aliases[j]);
1036 printed++; 1028 printed++;
1037 } 1029 }
1038 if (printed) 1030 if (printed && pager_in_use())
1039 printf("\n"); 1031 printf("\n");
1040out_free: 1032out_free:
1041 for (j = 0; j < len; j++) 1033 for (j = 0; j < len; j++)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index eb5f18b75402..b51a8bfb40f9 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -40,8 +40,7 @@
40#include "color.h" 40#include "color.h"
41#include "symbol.h" 41#include "symbol.h"
42#include "thread.h" 42#include "thread.h"
43#include <api/fs/debugfs.h> 43#include <api/fs/fs.h>
44#include <api/fs/tracefs.h>
45#include "trace-event.h" /* For __maybe_unused */ 44#include "trace-event.h" /* For __maybe_unused */
46#include "probe-event.h" 45#include "probe-event.h"
47#include "probe-finder.h" 46#include "probe-finder.h"
@@ -72,7 +71,7 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
72static struct machine *host_machine; 71static struct machine *host_machine;
73 72
74/* Initialize symbol maps and path of vmlinux/modules */ 73/* Initialize symbol maps and path of vmlinux/modules */
75static int init_symbol_maps(bool user_only) 74int init_probe_symbol_maps(bool user_only)
76{ 75{
77 int ret; 76 int ret;
78 77
@@ -102,7 +101,7 @@ out:
102 return ret; 101 return ret;
103} 102}
104 103
105static void exit_symbol_maps(void) 104void exit_probe_symbol_maps(void)
106{ 105{
107 if (host_machine) { 106 if (host_machine) {
108 machine__delete(host_machine); 107 machine__delete(host_machine);
@@ -127,17 +126,19 @@ static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void)
127{ 126{
128 /* kmap->ref_reloc_sym should be set if host_machine is initialized */ 127 /* kmap->ref_reloc_sym should be set if host_machine is initialized */
129 struct kmap *kmap; 128 struct kmap *kmap;
129 struct map *map = machine__kernel_map(host_machine);
130 130
131 if (map__load(host_machine->vmlinux_maps[MAP__FUNCTION], NULL) < 0) 131 if (map__load(map, NULL) < 0)
132 return NULL; 132 return NULL;
133 133
134 kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]); 134 kmap = map__kmap(map);
135 if (!kmap) 135 if (!kmap)
136 return NULL; 136 return NULL;
137 return kmap->ref_reloc_sym; 137 return kmap->ref_reloc_sym;
138} 138}
139 139
140static u64 kernel_get_symbol_address_by_name(const char *name, bool reloc) 140static int kernel_get_symbol_address_by_name(const char *name, u64 *addr,
141 bool reloc, bool reladdr)
141{ 142{
142 struct ref_reloc_sym *reloc_sym; 143 struct ref_reloc_sym *reloc_sym;
143 struct symbol *sym; 144 struct symbol *sym;
@@ -146,12 +147,14 @@ static u64 kernel_get_symbol_address_by_name(const char *name, bool reloc)
146 /* ref_reloc_sym is just a label. Need a special fix*/ 147 /* ref_reloc_sym is just a label. Need a special fix*/
147 reloc_sym = kernel_get_ref_reloc_sym(); 148 reloc_sym = kernel_get_ref_reloc_sym();
148 if (reloc_sym && strcmp(name, reloc_sym->name) == 0) 149 if (reloc_sym && strcmp(name, reloc_sym->name) == 0)
149 return (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; 150 *addr = (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr;
150 else { 151 else {
151 sym = __find_kernel_function_by_name(name, &map); 152 sym = __find_kernel_function_by_name(name, &map);
152 if (sym) 153 if (!sym)
153 return map->unmap_ip(map, sym->start) - 154 return -ENOENT;
154 ((reloc) ? 0 : map->reloc); 155 *addr = map->unmap_ip(map, sym->start) -
156 ((reloc) ? 0 : map->reloc) -
157 ((reladdr) ? map->start : 0);
155 } 158 }
156 return 0; 159 return 0;
157} 160}
@@ -245,12 +248,14 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
245static bool kprobe_blacklist__listed(unsigned long address); 248static bool kprobe_blacklist__listed(unsigned long address);
246static bool kprobe_warn_out_range(const char *symbol, unsigned long address) 249static bool kprobe_warn_out_range(const char *symbol, unsigned long address)
247{ 250{
248 u64 etext_addr; 251 u64 etext_addr = 0;
252 int ret;
249 253
250 /* Get the address of _etext for checking non-probable text symbol */ 254 /* Get the address of _etext for checking non-probable text symbol */
251 etext_addr = kernel_get_symbol_address_by_name("_etext", false); 255 ret = kernel_get_symbol_address_by_name("_etext", &etext_addr,
256 false, false);
252 257
253 if (etext_addr != 0 && etext_addr < address) 258 if (ret == 0 && etext_addr < address)
254 pr_warning("%s is out of .text, skip it.\n", symbol); 259 pr_warning("%s is out of .text, skip it.\n", symbol);
255 else if (kprobe_blacklist__listed(address)) 260 else if (kprobe_blacklist__listed(address))
256 pr_warning("%s is blacklisted function, skip it.\n", symbol); 261 pr_warning("%s is blacklisted function, skip it.\n", symbol);
@@ -270,18 +275,19 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso)
270 int ret = 0; 275 int ret = 0;
271 276
272 if (module) { 277 if (module) {
273 list_for_each_entry(dso, &host_machine->dsos.head, node) { 278 char module_name[128];
274 if (!dso->kernel) 279
275 continue; 280 snprintf(module_name, sizeof(module_name), "[%s]", module);
276 if (strncmp(dso->short_name + 1, module, 281 map = map_groups__find_by_name(&host_machine->kmaps, MAP__FUNCTION, module_name);
277 dso->short_name_len - 2) == 0) 282 if (map) {
278 goto found; 283 dso = map->dso;
284 goto found;
279 } 285 }
280 pr_debug("Failed to find module %s.\n", module); 286 pr_debug("Failed to find module %s.\n", module);
281 return -ENOENT; 287 return -ENOENT;
282 } 288 }
283 289
284 map = host_machine->vmlinux_maps[MAP__FUNCTION]; 290 map = machine__kernel_map(host_machine);
285 dso = map->dso; 291 dso = map->dso;
286 292
287 vmlinux_name = symbol_conf.vmlinux_name; 293 vmlinux_name = symbol_conf.vmlinux_name;
@@ -435,19 +441,22 @@ static char *debuginfo_cache_path;
435 441
436static struct debuginfo *debuginfo_cache__open(const char *module, bool silent) 442static struct debuginfo *debuginfo_cache__open(const char *module, bool silent)
437{ 443{
438 if ((debuginfo_cache_path && !strcmp(debuginfo_cache_path, module)) || 444 const char *path = module;
439 (!debuginfo_cache_path && !module && debuginfo_cache)) 445
446 /* If the module is NULL, it should be the kernel. */
447 if (!module)
448 path = "kernel";
449
450 if (debuginfo_cache_path && !strcmp(debuginfo_cache_path, path))
440 goto out; 451 goto out;
441 452
442 /* Copy module path */ 453 /* Copy module path */
443 free(debuginfo_cache_path); 454 free(debuginfo_cache_path);
444 if (module) { 455 debuginfo_cache_path = strdup(path);
445 debuginfo_cache_path = strdup(module); 456 if (!debuginfo_cache_path) {
446 if (!debuginfo_cache_path) { 457 debuginfo__delete(debuginfo_cache);
447 debuginfo__delete(debuginfo_cache); 458 debuginfo_cache = NULL;
448 debuginfo_cache = NULL; 459 goto out;
449 goto out;
450 }
451 } 460 }
452 461
453 debuginfo_cache = open_debuginfo(module, silent); 462 debuginfo_cache = open_debuginfo(module, silent);
@@ -516,8 +525,10 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
516 goto error; 525 goto error;
517 addr += stext; 526 addr += stext;
518 } else if (tp->symbol) { 527 } else if (tp->symbol) {
519 addr = kernel_get_symbol_address_by_name(tp->symbol, false); 528 /* If the module is given, this returns relative address */
520 if (addr == 0) 529 ret = kernel_get_symbol_address_by_name(tp->symbol, &addr,
530 false, !!tp->module);
531 if (ret != 0)
521 goto error; 532 goto error;
522 addr += tp->offset; 533 addr += tp->offset;
523 } 534 }
@@ -860,11 +871,11 @@ int show_line_range(struct line_range *lr, const char *module, bool user)
860{ 871{
861 int ret; 872 int ret;
862 873
863 ret = init_symbol_maps(user); 874 ret = init_probe_symbol_maps(user);
864 if (ret < 0) 875 if (ret < 0)
865 return ret; 876 return ret;
866 ret = __show_line_range(lr, module, user); 877 ret = __show_line_range(lr, module, user);
867 exit_symbol_maps(); 878 exit_probe_symbol_maps();
868 879
869 return ret; 880 return ret;
870} 881}
@@ -942,7 +953,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
942 int i, ret = 0; 953 int i, ret = 0;
943 struct debuginfo *dinfo; 954 struct debuginfo *dinfo;
944 955
945 ret = init_symbol_maps(pevs->uprobes); 956 ret = init_probe_symbol_maps(pevs->uprobes);
946 if (ret < 0) 957 if (ret < 0)
947 return ret; 958 return ret;
948 959
@@ -959,7 +970,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
959 970
960 debuginfo__delete(dinfo); 971 debuginfo__delete(dinfo);
961out: 972out:
962 exit_symbol_maps(); 973 exit_probe_symbol_maps();
963 return ret; 974 return ret;
964} 975}
965 976
@@ -1883,8 +1894,12 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
1883 goto out; 1894 goto out;
1884 sym = map__find_symbol(map, addr, NULL); 1895 sym = map__find_symbol(map, addr, NULL);
1885 } else { 1896 } else {
1886 if (tp->symbol) 1897 if (tp->symbol && !addr) {
1887 addr = kernel_get_symbol_address_by_name(tp->symbol, true); 1898 ret = kernel_get_symbol_address_by_name(tp->symbol,
1899 &addr, true, false);
1900 if (ret < 0)
1901 goto out;
1902 }
1888 if (addr) { 1903 if (addr) {
1889 addr += tp->offset; 1904 addr += tp->offset;
1890 sym = __find_kernel_function(addr, &map); 1905 sym = __find_kernel_function(addr, &map);
@@ -2054,7 +2069,7 @@ static void kprobe_blacklist__delete(struct list_head *blacklist)
2054static int kprobe_blacklist__load(struct list_head *blacklist) 2069static int kprobe_blacklist__load(struct list_head *blacklist)
2055{ 2070{
2056 struct kprobe_blacklist_node *node; 2071 struct kprobe_blacklist_node *node;
2057 const char *__debugfs = debugfs_find_mountpoint(); 2072 const char *__debugfs = debugfs__mountpoint();
2058 char buf[PATH_MAX], *p; 2073 char buf[PATH_MAX], *p;
2059 FILE *fp; 2074 FILE *fp;
2060 int ret; 2075 int ret;
@@ -2180,9 +2195,9 @@ out:
2180} 2195}
2181 2196
2182/* Show an event */ 2197/* Show an event */
2183static int show_perf_probe_event(const char *group, const char *event, 2198int show_perf_probe_event(const char *group, const char *event,
2184 struct perf_probe_event *pev, 2199 struct perf_probe_event *pev,
2185 const char *module, bool use_stdout) 2200 const char *module, bool use_stdout)
2186{ 2201{
2187 struct strbuf buf = STRBUF_INIT; 2202 struct strbuf buf = STRBUF_INIT;
2188 int ret; 2203 int ret;
@@ -2263,7 +2278,7 @@ int show_perf_probe_events(struct strfilter *filter)
2263 2278
2264 setup_pager(); 2279 setup_pager();
2265 2280
2266 ret = init_symbol_maps(false); 2281 ret = init_probe_symbol_maps(false);
2267 if (ret < 0) 2282 if (ret < 0)
2268 return ret; 2283 return ret;
2269 2284
@@ -2279,7 +2294,7 @@ int show_perf_probe_events(struct strfilter *filter)
2279 close(kp_fd); 2294 close(kp_fd);
2280 if (up_fd > 0) 2295 if (up_fd > 0)
2281 close(up_fd); 2296 close(up_fd);
2282 exit_symbol_maps(); 2297 exit_probe_symbol_maps();
2283 2298
2284 return ret; 2299 return ret;
2285} 2300}
@@ -2288,36 +2303,41 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
2288 struct strlist *namelist, bool allow_suffix) 2303 struct strlist *namelist, bool allow_suffix)
2289{ 2304{
2290 int i, ret; 2305 int i, ret;
2291 char *p; 2306 char *p, *nbase;
2292 2307
2293 if (*base == '.') 2308 if (*base == '.')
2294 base++; 2309 base++;
2310 nbase = strdup(base);
2311 if (!nbase)
2312 return -ENOMEM;
2295 2313
2296 /* Try no suffix */ 2314 /* Cut off the dot suffixes (e.g. .const, .isra)*/
2297 ret = e_snprintf(buf, len, "%s", base); 2315 p = strchr(nbase, '.');
2316 if (p && p != nbase)
2317 *p = '\0';
2318
2319 /* Try no suffix number */
2320 ret = e_snprintf(buf, len, "%s", nbase);
2298 if (ret < 0) { 2321 if (ret < 0) {
2299 pr_debug("snprintf() failed: %d\n", ret); 2322 pr_debug("snprintf() failed: %d\n", ret);
2300 return ret; 2323 goto out;
2301 } 2324 }
2302 /* Cut off the postfixes (e.g. .const, .isra)*/
2303 p = strchr(buf, '.');
2304 if (p && p != buf)
2305 *p = '\0';
2306 if (!strlist__has_entry(namelist, buf)) 2325 if (!strlist__has_entry(namelist, buf))
2307 return 0; 2326 goto out;
2308 2327
2309 if (!allow_suffix) { 2328 if (!allow_suffix) {
2310 pr_warning("Error: event \"%s\" already exists. " 2329 pr_warning("Error: event \"%s\" already exists. "
2311 "(Use -f to force duplicates.)\n", base); 2330 "(Use -f to force duplicates.)\n", buf);
2312 return -EEXIST; 2331 ret = -EEXIST;
2332 goto out;
2313 } 2333 }
2314 2334
2315 /* Try to add suffix */ 2335 /* Try to add suffix */
2316 for (i = 1; i < MAX_EVENT_INDEX; i++) { 2336 for (i = 1; i < MAX_EVENT_INDEX; i++) {
2317 ret = e_snprintf(buf, len, "%s_%d", base, i); 2337 ret = e_snprintf(buf, len, "%s_%d", nbase, i);
2318 if (ret < 0) { 2338 if (ret < 0) {
2319 pr_debug("snprintf() failed: %d\n", ret); 2339 pr_debug("snprintf() failed: %d\n", ret);
2320 return ret; 2340 goto out;
2321 } 2341 }
2322 if (!strlist__has_entry(namelist, buf)) 2342 if (!strlist__has_entry(namelist, buf))
2323 break; 2343 break;
@@ -2327,6 +2347,8 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
2327 ret = -ERANGE; 2347 ret = -ERANGE;
2328 } 2348 }
2329 2349
2350out:
2351 free(nbase);
2330 return ret; 2352 return ret;
2331} 2353}
2332 2354
@@ -2399,7 +2421,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
2399{ 2421{
2400 int i, fd, ret; 2422 int i, fd, ret;
2401 struct probe_trace_event *tev = NULL; 2423 struct probe_trace_event *tev = NULL;
2402 const char *event = NULL, *group = NULL;
2403 struct strlist *namelist; 2424 struct strlist *namelist;
2404 2425
2405 fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0)); 2426 fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0));
@@ -2415,7 +2436,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
2415 } 2436 }
2416 2437
2417 ret = 0; 2438 ret = 0;
2418 pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
2419 for (i = 0; i < ntevs; i++) { 2439 for (i = 0; i < ntevs; i++) {
2420 tev = &tevs[i]; 2440 tev = &tevs[i];
2421 /* Skip if the symbol is out of .text or blacklisted */ 2441 /* Skip if the symbol is out of .text or blacklisted */
@@ -2432,13 +2452,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
2432 if (ret < 0) 2452 if (ret < 0)
2433 break; 2453 break;
2434 2454
2435 /* We use tev's name for showing new events */
2436 show_perf_probe_event(tev->group, tev->event, pev,
2437 tev->point.module, false);
2438 /* Save the last valid name */
2439 event = tev->event;
2440 group = tev->group;
2441
2442 /* 2455 /*
2443 * Probes after the first probe which comes from same 2456 * Probes after the first probe which comes from same
2444 * user input are always allowed to add suffix, because 2457 * user input are always allowed to add suffix, because
@@ -2450,13 +2463,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
2450 if (ret == -EINVAL && pev->uprobes) 2463 if (ret == -EINVAL && pev->uprobes)
2451 warn_uprobe_event_compat(tev); 2464 warn_uprobe_event_compat(tev);
2452 2465
2453 /* Note that it is possible to skip all events because of blacklist */
2454 if (ret >= 0 && event) {
2455 /* Show how to use the event. */
2456 pr_info("\nYou can now use it in all perf tools, such as:\n\n");
2457 pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event);
2458 }
2459
2460 strlist__delete(namelist); 2466 strlist__delete(namelist);
2461close_out: 2467close_out:
2462 close(fd); 2468 close(fd);
@@ -2537,7 +2543,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2537 goto out; 2543 goto out;
2538 } 2544 }
2539 2545
2540 if (!pev->uprobes && !pp->retprobe) { 2546 /* Note that the symbols in the kmodule are not relocated */
2547 if (!pev->uprobes && !pp->retprobe && !pev->target) {
2541 reloc_sym = kernel_get_ref_reloc_sym(); 2548 reloc_sym = kernel_get_ref_reloc_sym();
2542 if (!reloc_sym) { 2549 if (!reloc_sym) {
2543 pr_warning("Relocated base symbol is not found!\n"); 2550 pr_warning("Relocated base symbol is not found!\n");
@@ -2574,8 +2581,9 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2574 } 2581 }
2575 /* Add one probe point */ 2582 /* Add one probe point */
2576 tp->address = map->unmap_ip(map, sym->start) + pp->offset; 2583 tp->address = map->unmap_ip(map, sym->start) + pp->offset;
2577 /* If we found a wrong one, mark it by NULL symbol */ 2584
2578 if (!pev->uprobes && 2585 /* Check the kprobe (not in module) is within .text */
2586 if (!pev->uprobes && !pev->target &&
2579 kprobe_warn_out_range(sym->name, tp->address)) { 2587 kprobe_warn_out_range(sym->name, tp->address)) {
2580 tp->symbol = NULL; /* Skip it */ 2588 tp->symbol = NULL; /* Skip it */
2581 skipped++; 2589 skipped++;
@@ -2759,63 +2767,71 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
2759 return find_probe_trace_events_from_map(pev, tevs); 2767 return find_probe_trace_events_from_map(pev, tevs);
2760} 2768}
2761 2769
2762struct __event_package { 2770int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)
2763 struct perf_probe_event *pev;
2764 struct probe_trace_event *tevs;
2765 int ntevs;
2766};
2767
2768int add_perf_probe_events(struct perf_probe_event *pevs, int npevs)
2769{ 2771{
2770 int i, j, ret; 2772 int i, ret;
2771 struct __event_package *pkgs;
2772
2773 ret = 0;
2774 pkgs = zalloc(sizeof(struct __event_package) * npevs);
2775
2776 if (pkgs == NULL)
2777 return -ENOMEM;
2778
2779 ret = init_symbol_maps(pevs->uprobes);
2780 if (ret < 0) {
2781 free(pkgs);
2782 return ret;
2783 }
2784 2773
2785 /* Loop 1: convert all events */ 2774 /* Loop 1: convert all events */
2786 for (i = 0; i < npevs; i++) { 2775 for (i = 0; i < npevs; i++) {
2787 pkgs[i].pev = &pevs[i];
2788 /* Init kprobe blacklist if needed */ 2776 /* Init kprobe blacklist if needed */
2789 if (!pkgs[i].pev->uprobes) 2777 if (!pevs[i].uprobes)
2790 kprobe_blacklist__init(); 2778 kprobe_blacklist__init();
2791 /* Convert with or without debuginfo */ 2779 /* Convert with or without debuginfo */
2792 ret = convert_to_probe_trace_events(pkgs[i].pev, 2780 ret = convert_to_probe_trace_events(&pevs[i], &pevs[i].tevs);
2793 &pkgs[i].tevs);
2794 if (ret < 0) 2781 if (ret < 0)
2795 goto end; 2782 return ret;
2796 pkgs[i].ntevs = ret; 2783 pevs[i].ntevs = ret;
2797 } 2784 }
2798 /* This just release blacklist only if allocated */ 2785 /* This just release blacklist only if allocated */
2799 kprobe_blacklist__release(); 2786 kprobe_blacklist__release();
2800 2787
2788 return 0;
2789}
2790
2791int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
2792{
2793 int i, ret = 0;
2794
2801 /* Loop 2: add all events */ 2795 /* Loop 2: add all events */
2802 for (i = 0; i < npevs; i++) { 2796 for (i = 0; i < npevs; i++) {
2803 ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs, 2797 ret = __add_probe_trace_events(&pevs[i], pevs[i].tevs,
2804 pkgs[i].ntevs, 2798 pevs[i].ntevs,
2805 probe_conf.force_add); 2799 probe_conf.force_add);
2806 if (ret < 0) 2800 if (ret < 0)
2807 break; 2801 break;
2808 } 2802 }
2809end: 2803 return ret;
2804}
2805
2806void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs)
2807{
2808 int i, j;
2809
2810 /* Loop 3: cleanup and free trace events */ 2810 /* Loop 3: cleanup and free trace events */
2811 for (i = 0; i < npevs; i++) { 2811 for (i = 0; i < npevs; i++) {
2812 for (j = 0; j < pkgs[i].ntevs; j++) 2812 for (j = 0; j < pevs[i].ntevs; j++)
2813 clear_probe_trace_event(&pkgs[i].tevs[j]); 2813 clear_probe_trace_event(&pevs[i].tevs[j]);
2814 zfree(&pkgs[i].tevs); 2814 zfree(&pevs[i].tevs);
2815 pevs[i].ntevs = 0;
2816 clear_perf_probe_event(&pevs[i]);
2815 } 2817 }
2816 free(pkgs); 2818}
2817 exit_symbol_maps();
2818 2819
2820int add_perf_probe_events(struct perf_probe_event *pevs, int npevs)
2821{
2822 int ret;
2823
2824 ret = init_probe_symbol_maps(pevs->uprobes);
2825 if (ret < 0)
2826 return ret;
2827
2828 ret = convert_perf_probe_events(pevs, npevs);
2829 if (ret == 0)
2830 ret = apply_perf_probe_events(pevs, npevs);
2831
2832 cleanup_perf_probe_events(pevs, npevs);
2833
2834 exit_probe_symbol_maps();
2819 return ret; 2835 return ret;
2820} 2836}
2821 2837
@@ -2827,8 +2843,6 @@ int del_perf_probe_events(struct strfilter *filter)
2827 if (!str) 2843 if (!str)
2828 return -EINVAL; 2844 return -EINVAL;
2829 2845
2830 pr_debug("Delete filter: \'%s\'\n", str);
2831
2832 /* Get current event names */ 2846 /* Get current event names */
2833 ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW); 2847 ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
2834 if (ret < 0) 2848 if (ret < 0)
@@ -2843,9 +2857,6 @@ int del_perf_probe_events(struct strfilter *filter)
2843 ret = ret2; 2857 ret = ret2;
2844 goto error; 2858 goto error;
2845 } 2859 }
2846 if (ret == -ENOENT && ret2 == -ENOENT)
2847 pr_debug("\"%s\" does not hit any event.\n", str);
2848 /* Note that this is silently ignored */
2849 ret = 0; 2860 ret = 0;
2850 2861
2851error: 2862error:
@@ -2880,7 +2891,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
2880 struct map *map; 2891 struct map *map;
2881 int ret; 2892 int ret;
2882 2893
2883 ret = init_symbol_maps(user); 2894 ret = init_probe_symbol_maps(user);
2884 if (ret < 0) 2895 if (ret < 0)
2885 return ret; 2896 return ret;
2886 2897
@@ -2910,7 +2921,7 @@ end:
2910 if (user) { 2921 if (user) {
2911 map__put(map); 2922 map__put(map);
2912 } 2923 }
2913 exit_symbol_maps(); 2924 exit_probe_symbol_maps();
2914 2925
2915 return ret; 2926 return ret;
2916} 2927}
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 6e7ec68a4aa8..ba926c30f8cd 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -87,6 +87,8 @@ struct perf_probe_event {
87 bool uprobes; /* Uprobe event flag */ 87 bool uprobes; /* Uprobe event flag */
88 char *target; /* Target binary */ 88 char *target; /* Target binary */
89 struct perf_probe_arg *args; /* Arguments */ 89 struct perf_probe_arg *args; /* Arguments */
90 struct probe_trace_event *tevs;
91 int ntevs;
90}; 92};
91 93
92/* Line range */ 94/* Line range */
@@ -108,6 +110,8 @@ struct variable_list {
108}; 110};
109 111
110struct map; 112struct map;
113int init_probe_symbol_maps(bool user_only);
114void exit_probe_symbol_maps(void);
111 115
112/* Command string to events */ 116/* Command string to events */
113extern int parse_perf_probe_command(const char *cmd, 117extern int parse_perf_probe_command(const char *cmd,
@@ -138,7 +142,14 @@ extern void line_range__clear(struct line_range *lr);
138extern int line_range__init(struct line_range *lr); 142extern int line_range__init(struct line_range *lr);
139 143
140extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs); 144extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
145extern int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
146extern int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
147extern void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
141extern int del_perf_probe_events(struct strfilter *filter); 148extern int del_perf_probe_events(struct strfilter *filter);
149
150extern int show_perf_probe_event(const char *group, const char *event,
151 struct perf_probe_event *pev,
152 const char *module, bool use_stdout);
142extern int show_perf_probe_events(struct strfilter *filter); 153extern int show_perf_probe_events(struct strfilter *filter);
143extern int show_line_range(struct line_range *lr, const char *module, 154extern int show_line_range(struct line_range *lr, const char *module,
144 bool user); 155 bool user);
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index bbb243717ec8..89dbeb92c68e 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -22,8 +22,7 @@
22#include "color.h" 22#include "color.h"
23#include "symbol.h" 23#include "symbol.h"
24#include "thread.h" 24#include "thread.h"
25#include <api/fs/debugfs.h> 25#include <api/fs/tracing_path.h>
26#include <api/fs/tracefs.h>
27#include "probe-event.h" 26#include "probe-event.h"
28#include "probe-file.h" 27#include "probe-file.h"
29#include "session.h" 28#include "session.h"
@@ -73,21 +72,11 @@ static void print_both_open_warning(int kerr, int uerr)
73static int open_probe_events(const char *trace_file, bool readwrite) 72static int open_probe_events(const char *trace_file, bool readwrite)
74{ 73{
75 char buf[PATH_MAX]; 74 char buf[PATH_MAX];
76 const char *__debugfs;
77 const char *tracing_dir = ""; 75 const char *tracing_dir = "";
78 int ret; 76 int ret;
79 77
80 __debugfs = tracefs_find_mountpoint();
81 if (__debugfs == NULL) {
82 tracing_dir = "tracing/";
83
84 __debugfs = debugfs_find_mountpoint();
85 if (__debugfs == NULL)
86 return -ENOTSUP;
87 }
88
89 ret = e_snprintf(buf, PATH_MAX, "%s/%s%s", 78 ret = e_snprintf(buf, PATH_MAX, "%s/%s%s",
90 __debugfs, tracing_dir, trace_file); 79 tracing_path, tracing_dir, trace_file);
91 if (ret >= 0) { 80 if (ret >= 0) {
92 pr_debug("Opening %s write=%d\n", buf, readwrite); 81 pr_debug("Opening %s write=%d\n", buf, readwrite);
93 if (readwrite && !probe_event_dry_run) 82 if (readwrite && !probe_event_dry_run)
@@ -267,7 +256,6 @@ static int __del_trace_probe_event(int fd, struct str_node *ent)
267 goto error; 256 goto error;
268 } 257 }
269 258
270 pr_info("Removed event: %s\n", ent->s);
271 return 0; 259 return 0;
272error: 260error:
273 pr_warning("Failed to delete event: %s\n", 261 pr_warning("Failed to delete event: %s\n",
@@ -275,7 +263,8 @@ error:
275 return ret; 263 return ret;
276} 264}
277 265
278int probe_file__del_events(int fd, struct strfilter *filter) 266int probe_file__get_events(int fd, struct strfilter *filter,
267 struct strlist *plist)
279{ 268{
280 struct strlist *namelist; 269 struct strlist *namelist;
281 struct str_node *ent; 270 struct str_node *ent;
@@ -290,12 +279,43 @@ int probe_file__del_events(int fd, struct strfilter *filter)
290 p = strchr(ent->s, ':'); 279 p = strchr(ent->s, ':');
291 if ((p && strfilter__compare(filter, p + 1)) || 280 if ((p && strfilter__compare(filter, p + 1)) ||
292 strfilter__compare(filter, ent->s)) { 281 strfilter__compare(filter, ent->s)) {
293 ret = __del_trace_probe_event(fd, ent); 282 strlist__add(plist, ent->s);
294 if (ret < 0) 283 ret = 0;
295 break;
296 } 284 }
297 } 285 }
298 strlist__delete(namelist); 286 strlist__delete(namelist);
299 287
300 return ret; 288 return ret;
301} 289}
290
291int probe_file__del_strlist(int fd, struct strlist *namelist)
292{
293 int ret = 0;
294 struct str_node *ent;
295
296 strlist__for_each(ent, namelist) {
297 ret = __del_trace_probe_event(fd, ent);
298 if (ret < 0)
299 break;
300 }
301 return ret;
302}
303
304int probe_file__del_events(int fd, struct strfilter *filter)
305{
306 struct strlist *namelist;
307 int ret;
308
309 namelist = strlist__new(NULL, NULL);
310 if (!namelist)
311 return -ENOMEM;
312
313 ret = probe_file__get_events(fd, filter, namelist);
314 if (ret < 0)
315 return ret;
316
317 ret = probe_file__del_strlist(fd, namelist);
318 strlist__delete(namelist);
319
320 return ret;
321}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index ada94a242a17..18ac9cf51c34 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -14,5 +14,9 @@ struct strlist *probe_file__get_namelist(int fd);
14struct strlist *probe_file__get_rawlist(int fd); 14struct strlist *probe_file__get_rawlist(int fd);
15int probe_file__add_event(int fd, struct probe_trace_event *tev); 15int probe_file__add_event(int fd, struct probe_trace_event *tev);
16int probe_file__del_events(int fd, struct strfilter *filter); 16int probe_file__del_events(int fd, struct strfilter *filter);
17int probe_file__get_events(int fd, struct strfilter *filter,
18 struct strlist *plist);
19int probe_file__del_strlist(int fd, struct strlist *namelist);
20
17 21
18#endif 22#endif
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 29c43c0680a8..bd8f03de5e40 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -70,6 +70,7 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
70 if (!dbg->dwfl) 70 if (!dbg->dwfl)
71 goto error; 71 goto error;
72 72
73 dwfl_report_begin(dbg->dwfl);
73 dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd); 74 dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd);
74 if (!dbg->mod) 75 if (!dbg->mod)
75 goto error; 76 goto error;
@@ -78,6 +79,8 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
78 if (!dbg->dbg) 79 if (!dbg->dbg)
79 goto error; 80 goto error;
80 81
82 dwfl_report_end(dbg->dwfl, NULL, NULL);
83
81 return 0; 84 return 0;
82error: 85error:
83 if (dbg->dwfl) 86 if (dbg->dwfl)
@@ -591,6 +594,7 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
591/* Convert subprogram DIE to trace point */ 594/* Convert subprogram DIE to trace point */
592static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, 595static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
593 Dwarf_Addr paddr, bool retprobe, 596 Dwarf_Addr paddr, bool retprobe,
597 const char *function,
594 struct probe_trace_point *tp) 598 struct probe_trace_point *tp)
595{ 599{
596 Dwarf_Addr eaddr, highaddr; 600 Dwarf_Addr eaddr, highaddr;
@@ -634,8 +638,10 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
634 /* Return probe must be on the head of a subprogram */ 638 /* Return probe must be on the head of a subprogram */
635 if (retprobe) { 639 if (retprobe) {
636 if (eaddr != paddr) { 640 if (eaddr != paddr) {
637 pr_warning("Return probe must be on the head of" 641 pr_warning("Failed to find \"%s%%return\",\n"
638 " a real function.\n"); 642 " because %s is an inlined function and"
643 " has no return point.\n", function,
644 function);
639 return -EINVAL; 645 return -EINVAL;
640 } 646 }
641 tp->retprobe = true; 647 tp->retprobe = true;
@@ -1175,6 +1181,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1175{ 1181{
1176 struct trace_event_finder *tf = 1182 struct trace_event_finder *tf =
1177 container_of(pf, struct trace_event_finder, pf); 1183 container_of(pf, struct trace_event_finder, pf);
1184 struct perf_probe_point *pp = &pf->pev->point;
1178 struct probe_trace_event *tev; 1185 struct probe_trace_event *tev;
1179 struct perf_probe_arg *args; 1186 struct perf_probe_arg *args;
1180 int ret, i; 1187 int ret, i;
@@ -1189,7 +1196,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1189 1196
1190 /* Trace point should be converted from subprogram DIE */ 1197 /* Trace point should be converted from subprogram DIE */
1191 ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, 1198 ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
1192 pf->pev->point.retprobe, &tev->point); 1199 pp->retprobe, pp->function, &tev->point);
1193 if (ret < 0) 1200 if (ret < 0)
1194 return ret; 1201 return ret;
1195 1202
@@ -1319,6 +1326,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
1319{ 1326{
1320 struct available_var_finder *af = 1327 struct available_var_finder *af =
1321 container_of(pf, struct available_var_finder, pf); 1328 container_of(pf, struct available_var_finder, pf);
1329 struct perf_probe_point *pp = &pf->pev->point;
1322 struct variable_list *vl; 1330 struct variable_list *vl;
1323 Dwarf_Die die_mem; 1331 Dwarf_Die die_mem;
1324 int ret; 1332 int ret;
@@ -1332,7 +1340,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
1332 1340
1333 /* Trace point should be converted from subprogram DIE */ 1341 /* Trace point should be converted from subprogram DIE */
1334 ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr, 1342 ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
1335 pf->pev->point.retprobe, &vl->point); 1343 pp->retprobe, pp->function, &vl->point);
1336 if (ret < 0) 1344 if (ret < 0)
1337 return ret; 1345 return ret;
1338 1346
@@ -1399,6 +1407,41 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg,
1399 return (ret < 0) ? ret : af.nvls; 1407 return (ret < 0) ? ret : af.nvls;
1400} 1408}
1401 1409
1410/* For the kernel module, we need a special code to get a DIE */
1411static int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs)
1412{
1413 int n, i;
1414 Elf32_Word shndx;
1415 Elf_Scn *scn;
1416 Elf *elf;
1417 GElf_Shdr mem, *shdr;
1418 const char *p;
1419
1420 elf = dwfl_module_getelf(dbg->mod, &dbg->bias);
1421 if (!elf)
1422 return -EINVAL;
1423
1424 /* Get the number of relocations */
1425 n = dwfl_module_relocations(dbg->mod);
1426 if (n < 0)
1427 return -ENOENT;
1428 /* Search the relocation related .text section */
1429 for (i = 0; i < n; i++) {
1430 p = dwfl_module_relocation_info(dbg->mod, i, &shndx);
1431 if (strcmp(p, ".text") == 0) {
1432 /* OK, get the section header */
1433 scn = elf_getscn(elf, shndx);
1434 if (!scn)
1435 return -ENOENT;
1436 shdr = gelf_getshdr(scn, &mem);
1437 if (!shdr)
1438 return -ENOENT;
1439 *offs = shdr->sh_addr;
1440 }
1441 }
1442 return 0;
1443}
1444
1402/* Reverse search */ 1445/* Reverse search */
1403int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr, 1446int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
1404 struct perf_probe_point *ppt) 1447 struct perf_probe_point *ppt)
@@ -1407,9 +1450,16 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
1407 Dwarf_Addr _addr = 0, baseaddr = 0; 1450 Dwarf_Addr _addr = 0, baseaddr = 0;
1408 const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp; 1451 const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
1409 int baseline = 0, lineno = 0, ret = 0; 1452 int baseline = 0, lineno = 0, ret = 0;
1453 bool reloc = false;
1410 1454
1455retry:
1411 /* Find cu die */ 1456 /* Find cu die */
1412 if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) { 1457 if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) {
1458 if (!reloc && debuginfo__get_text_offset(dbg, &baseaddr) == 0) {
1459 addr += baseaddr;
1460 reloc = true;
1461 goto retry;
1462 }
1413 pr_warning("Failed to find debug information for address %lx\n", 1463 pr_warning("Failed to find debug information for address %lx\n",
1414 addr); 1464 addr);
1415 ret = -EINVAL; 1465 ret = -EINVAL;
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 6324fe6b161e..98f127abfa42 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -67,6 +67,7 @@ static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
67static PyMemberDef pyrf_mmap_event__members[] = { 67static PyMemberDef pyrf_mmap_event__members[] = {
68 sample_members 68 sample_members
69 member_def(perf_event_header, type, T_UINT, "event type"), 69 member_def(perf_event_header, type, T_UINT, "event type"),
70 member_def(perf_event_header, misc, T_UINT, "event misc"),
70 member_def(mmap_event, pid, T_UINT, "event pid"), 71 member_def(mmap_event, pid, T_UINT, "event pid"),
71 member_def(mmap_event, tid, T_UINT, "event tid"), 72 member_def(mmap_event, tid, T_UINT, "event tid"),
72 member_def(mmap_event, start, T_ULONGLONG, "start of the map"), 73 member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
@@ -297,6 +298,43 @@ static PyTypeObject pyrf_sample_event__type = {
297 .tp_repr = (reprfunc)pyrf_sample_event__repr, 298 .tp_repr = (reprfunc)pyrf_sample_event__repr,
298}; 299};
299 300
301static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
302
303static PyMemberDef pyrf_context_switch_event__members[] = {
304 sample_members
305 member_def(perf_event_header, type, T_UINT, "event type"),
306 member_def(context_switch_event, next_prev_pid, T_UINT, "next/prev pid"),
307 member_def(context_switch_event, next_prev_tid, T_UINT, "next/prev tid"),
308 { .name = NULL, },
309};
310
311static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent)
312{
313 PyObject *ret;
314 char *s;
315
316 if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
317 pevent->event.context_switch.next_prev_pid,
318 pevent->event.context_switch.next_prev_tid,
319 !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
320 ret = PyErr_NoMemory();
321 } else {
322 ret = PyString_FromString(s);
323 free(s);
324 }
325 return ret;
326}
327
328static PyTypeObject pyrf_context_switch_event__type = {
329 PyVarObject_HEAD_INIT(NULL, 0)
330 .tp_name = "perf.context_switch_event",
331 .tp_basicsize = sizeof(struct pyrf_event),
332 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
333 .tp_doc = pyrf_context_switch_event__doc,
334 .tp_members = pyrf_context_switch_event__members,
335 .tp_repr = (reprfunc)pyrf_context_switch_event__repr,
336};
337
300static int pyrf_event__setup_types(void) 338static int pyrf_event__setup_types(void)
301{ 339{
302 int err; 340 int err;
@@ -306,6 +344,7 @@ static int pyrf_event__setup_types(void)
306 pyrf_lost_event__type.tp_new = 344 pyrf_lost_event__type.tp_new =
307 pyrf_read_event__type.tp_new = 345 pyrf_read_event__type.tp_new =
308 pyrf_sample_event__type.tp_new = 346 pyrf_sample_event__type.tp_new =
347 pyrf_context_switch_event__type.tp_new =
309 pyrf_throttle_event__type.tp_new = PyType_GenericNew; 348 pyrf_throttle_event__type.tp_new = PyType_GenericNew;
310 err = PyType_Ready(&pyrf_mmap_event__type); 349 err = PyType_Ready(&pyrf_mmap_event__type);
311 if (err < 0) 350 if (err < 0)
@@ -328,6 +367,9 @@ static int pyrf_event__setup_types(void)
328 err = PyType_Ready(&pyrf_sample_event__type); 367 err = PyType_Ready(&pyrf_sample_event__type);
329 if (err < 0) 368 if (err < 0)
330 goto out; 369 goto out;
370 err = PyType_Ready(&pyrf_context_switch_event__type);
371 if (err < 0)
372 goto out;
331out: 373out:
332 return err; 374 return err;
333} 375}
@@ -342,6 +384,8 @@ static PyTypeObject *pyrf_event__type[] = {
342 [PERF_RECORD_FORK] = &pyrf_task_event__type, 384 [PERF_RECORD_FORK] = &pyrf_task_event__type,
343 [PERF_RECORD_READ] = &pyrf_read_event__type, 385 [PERF_RECORD_READ] = &pyrf_read_event__type,
344 [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type, 386 [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type,
387 [PERF_RECORD_SWITCH] = &pyrf_context_switch_event__type,
388 [PERF_RECORD_SWITCH_CPU_WIDE] = &pyrf_context_switch_event__type,
345}; 389};
346 390
347static PyObject *pyrf_event__new(union perf_event *event) 391static PyObject *pyrf_event__new(union perf_event *event)
@@ -349,8 +393,10 @@ static PyObject *pyrf_event__new(union perf_event *event)
349 struct pyrf_event *pevent; 393 struct pyrf_event *pevent;
350 PyTypeObject *ptype; 394 PyTypeObject *ptype;
351 395
352 if (event->header.type < PERF_RECORD_MMAP || 396 if ((event->header.type < PERF_RECORD_MMAP ||
353 event->header.type > PERF_RECORD_SAMPLE) 397 event->header.type > PERF_RECORD_SAMPLE) &&
398 !(event->header.type == PERF_RECORD_SWITCH ||
399 event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
354 return NULL; 400 return NULL;
355 401
356 ptype = pyrf_event__type[event->header.type]; 402 ptype = pyrf_event__type[event->header.type];
@@ -528,6 +574,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
528 "exclude_hv", 574 "exclude_hv",
529 "exclude_idle", 575 "exclude_idle",
530 "mmap", 576 "mmap",
577 "context_switch",
531 "comm", 578 "comm",
532 "freq", 579 "freq",
533 "inherit_stat", 580 "inherit_stat",
@@ -553,6 +600,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
553 exclude_hv = 0, 600 exclude_hv = 0,
554 exclude_idle = 0, 601 exclude_idle = 0,
555 mmap = 0, 602 mmap = 0,
603 context_switch = 0,
556 comm = 0, 604 comm = 0,
557 freq = 1, 605 freq = 1,
558 inherit_stat = 0, 606 inherit_stat = 0,
@@ -565,13 +613,13 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
565 int idx = 0; 613 int idx = 0;
566 614
567 if (!PyArg_ParseTupleAndKeywords(args, kwargs, 615 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
568 "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist, 616 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
569 &attr.type, &attr.config, &attr.sample_freq, 617 &attr.type, &attr.config, &attr.sample_freq,
570 &sample_period, &attr.sample_type, 618 &sample_period, &attr.sample_type,
571 &attr.read_format, &disabled, &inherit, 619 &attr.read_format, &disabled, &inherit,
572 &pinned, &exclusive, &exclude_user, 620 &pinned, &exclusive, &exclude_user,
573 &exclude_kernel, &exclude_hv, &exclude_idle, 621 &exclude_kernel, &exclude_hv, &exclude_idle,
574 &mmap, &comm, &freq, &inherit_stat, 622 &mmap, &context_switch, &comm, &freq, &inherit_stat,
575 &enable_on_exec, &task, &watermark, 623 &enable_on_exec, &task, &watermark,
576 &precise_ip, &mmap_data, &sample_id_all, 624 &precise_ip, &mmap_data, &sample_id_all,
577 &attr.wakeup_events, &attr.bp_type, 625 &attr.wakeup_events, &attr.bp_type,
@@ -595,6 +643,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
595 attr.exclude_hv = exclude_hv; 643 attr.exclude_hv = exclude_hv;
596 attr.exclude_idle = exclude_idle; 644 attr.exclude_idle = exclude_idle;
597 attr.mmap = mmap; 645 attr.mmap = mmap;
646 attr.context_switch = context_switch;
598 attr.comm = comm; 647 attr.comm = comm;
599 attr.freq = freq; 648 attr.freq = freq;
600 attr.inherit_stat = inherit_stat; 649 attr.inherit_stat = inherit_stat;
@@ -1019,6 +1068,8 @@ static struct {
1019 PERF_CONST(RECORD_LOST_SAMPLES), 1068 PERF_CONST(RECORD_LOST_SAMPLES),
1020 PERF_CONST(RECORD_SWITCH), 1069 PERF_CONST(RECORD_SWITCH),
1021 PERF_CONST(RECORD_SWITCH_CPU_WIDE), 1070 PERF_CONST(RECORD_SWITCH_CPU_WIDE),
1071
1072 PERF_CONST(RECORD_MISC_SWITCH_OUT),
1022 { .name = NULL, }, 1073 { .name = NULL, },
1023}; 1074};
1024 1075
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 1bd593bbf7a5..544509c159ce 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -221,6 +221,7 @@ static void define_event_symbols(struct event_format *event,
221 break; 221 break;
222 case PRINT_BSTRING: 222 case PRINT_BSTRING:
223 case PRINT_DYNAMIC_ARRAY: 223 case PRINT_DYNAMIC_ARRAY:
224 case PRINT_DYNAMIC_ARRAY_LEN:
224 case PRINT_STRING: 225 case PRINT_STRING:
225 case PRINT_BITMASK: 226 case PRINT_BITMASK:
226 break; 227 break;
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index ace2484985cb..a8e825fca42a 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -251,6 +251,7 @@ static void define_event_symbols(struct event_format *event,
251 /* gcc warns for these? */ 251 /* gcc warns for these? */
252 case PRINT_BSTRING: 252 case PRINT_BSTRING:
253 case PRINT_DYNAMIC_ARRAY: 253 case PRINT_DYNAMIC_ARRAY:
254 case PRINT_DYNAMIC_ARRAY_LEN:
254 case PRINT_FUNC: 255 case PRINT_FUNC:
255 case PRINT_BITMASK: 256 case PRINT_BITMASK:
256 /* we should warn... */ 257 /* we should warn... */
@@ -318,7 +319,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
318 319
319 if (thread__resolve_callchain(al->thread, evsel, 320 if (thread__resolve_callchain(al->thread, evsel,
320 sample, NULL, NULL, 321 sample, NULL, NULL,
321 PERF_MAX_STACK_DEPTH) != 0) { 322 scripting_max_stack) != 0) {
322 pr_err("Failed to resolve callchain. Skipping\n"); 323 pr_err("Failed to resolve callchain. Skipping\n");
323 goto exit; 324 goto exit;
324 } 325 }
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8a4537ee9bc3..428149bc64d2 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -138,6 +138,8 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
138 perf_session__set_id_hdr_size(session); 138 perf_session__set_id_hdr_size(session);
139 perf_session__set_comm_exec(session); 139 perf_session__set_comm_exec(session);
140 } 140 }
141 } else {
142 session->machines.host.env = &perf_env;
141 } 143 }
142 144
143 if (!file || perf_data_file__is_write(file)) { 145 if (!file || perf_data_file__is_write(file)) {
@@ -170,30 +172,13 @@ static void perf_session__delete_threads(struct perf_session *session)
170 machine__delete_threads(&session->machines.host); 172 machine__delete_threads(&session->machines.host);
171} 173}
172 174
173static void perf_session_env__exit(struct perf_env *env)
174{
175 zfree(&env->hostname);
176 zfree(&env->os_release);
177 zfree(&env->version);
178 zfree(&env->arch);
179 zfree(&env->cpu_desc);
180 zfree(&env->cpuid);
181
182 zfree(&env->cmdline);
183 zfree(&env->cmdline_argv);
184 zfree(&env->sibling_cores);
185 zfree(&env->sibling_threads);
186 zfree(&env->numa_nodes);
187 zfree(&env->pmu_mappings);
188}
189
190void perf_session__delete(struct perf_session *session) 175void perf_session__delete(struct perf_session *session)
191{ 176{
192 auxtrace__free(session); 177 auxtrace__free(session);
193 auxtrace_index__free(&session->auxtrace_index); 178 auxtrace_index__free(&session->auxtrace_index);
194 perf_session__destroy_kernel_maps(session); 179 perf_session__destroy_kernel_maps(session);
195 perf_session__delete_threads(session); 180 perf_session__delete_threads(session);
196 perf_session_env__exit(&session->header.env); 181 perf_env__exit(&session->header.env);
197 machines__exit(&session->machines); 182 machines__exit(&session->machines);
198 if (session->file) 183 if (session->file)
199 perf_data_file__close(session->file); 184 perf_data_file__close(session->file);
@@ -1079,11 +1064,11 @@ static int machines__deliver_event(struct machines *machines,
1079 1064
1080 switch (event->header.type) { 1065 switch (event->header.type) {
1081 case PERF_RECORD_SAMPLE: 1066 case PERF_RECORD_SAMPLE:
1082 dump_sample(evsel, event, sample);
1083 if (evsel == NULL) { 1067 if (evsel == NULL) {
1084 ++evlist->stats.nr_unknown_id; 1068 ++evlist->stats.nr_unknown_id;
1085 return 0; 1069 return 0;
1086 } 1070 }
1071 dump_sample(evsel, event, sample);
1087 if (machine == NULL) { 1072 if (machine == NULL) {
1088 ++evlist->stats.nr_unprocessable_samples; 1073 ++evlist->stats.nr_unprocessable_samples;
1089 return 0; 1074 return 0;
@@ -1116,6 +1101,9 @@ static int machines__deliver_event(struct machines *machines,
1116 case PERF_RECORD_UNTHROTTLE: 1101 case PERF_RECORD_UNTHROTTLE:
1117 return tool->unthrottle(tool, event, sample, machine); 1102 return tool->unthrottle(tool, event, sample, machine);
1118 case PERF_RECORD_AUX: 1103 case PERF_RECORD_AUX:
1104 if (tool->aux == perf_event__process_aux &&
1105 (event->aux.flags & PERF_AUX_FLAG_TRUNCATED))
1106 evlist->stats.total_aux_lost += 1;
1119 return tool->aux(tool, event, sample, machine); 1107 return tool->aux(tool, event, sample, machine);
1120 case PERF_RECORD_ITRACE_START: 1108 case PERF_RECORD_ITRACE_START:
1121 return tool->itrace_start(tool, event, sample, machine); 1109 return tool->itrace_start(tool, event, sample, machine);
@@ -1323,7 +1311,7 @@ struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
1323 return machine__findnew_thread(&session->machines.host, -1, pid); 1311 return machine__findnew_thread(&session->machines.host, -1, pid);
1324} 1312}
1325 1313
1326static struct thread *perf_session__register_idle_thread(struct perf_session *session) 1314struct thread *perf_session__register_idle_thread(struct perf_session *session)
1327{ 1315{
1328 struct thread *thread; 1316 struct thread *thread;
1329 1317
@@ -1361,6 +1349,13 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
1361 } 1349 }
1362 } 1350 }
1363 1351
1352 if (session->tool->aux == perf_event__process_aux &&
1353 stats->total_aux_lost != 0) {
1354 ui__warning("AUX data lost %" PRIu64 " times out of %u!\n\n",
1355 stats->total_aux_lost,
1356 stats->nr_events[PERF_RECORD_AUX]);
1357 }
1358
1364 if (stats->nr_unknown_events != 0) { 1359 if (stats->nr_unknown_events != 0) {
1365 ui__warning("Found %u unknown events!\n\n" 1360 ui__warning("Found %u unknown events!\n\n"
1366 "Is this an older tool processing a perf.data " 1361 "Is this an older tool processing a perf.data "
@@ -1580,7 +1575,10 @@ static int __perf_session__process_events(struct perf_session *session,
1580 file_offset = page_offset; 1575 file_offset = page_offset;
1581 head = data_offset - page_offset; 1576 head = data_offset - page_offset;
1582 1577
1583 if (data_size && (data_offset + data_size < file_size)) 1578 if (data_size == 0)
1579 goto out;
1580
1581 if (data_offset + data_size < file_size)
1584 file_size = data_offset + data_size; 1582 file_size = data_offset + data_size;
1585 1583
1586 ui_progress__init(&prog, file_size, "Processing events..."); 1584 ui_progress__init(&prog, file_size, "Processing events...");
@@ -1802,7 +1800,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
1802 1800
1803 if (thread__resolve_callchain(al->thread, evsel, 1801 if (thread__resolve_callchain(al->thread, evsel,
1804 sample, NULL, NULL, 1802 sample, NULL, NULL,
1805 PERF_MAX_STACK_DEPTH) != 0) { 1803 stack_depth) != 0) {
1806 if (verbose) 1804 if (verbose)
1807 error("Failed to resolve callchain. Skipping\n"); 1805 error("Failed to resolve callchain. Skipping\n");
1808 return; 1806 return;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index b44afc75d1cc..3e900c0efc73 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -89,6 +89,8 @@ struct machine *perf_session__findnew_machine(struct perf_session *session, pid_
89} 89}
90 90
91struct thread *perf_session__findnew(struct perf_session *session, pid_t pid); 91struct thread *perf_session__findnew(struct perf_session *session, pid_t pid);
92struct thread *perf_session__register_idle_thread(struct perf_session *session);
93
92size_t perf_session__fprintf(struct perf_session *session, FILE *fp); 94size_t perf_session__fprintf(struct perf_session *session, FILE *fp);
93 95
94size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp); 96size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp);
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 7e3871606df3..2d8ccd4d9e1b 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -21,6 +21,7 @@ int sort__need_collapse = 0;
21int sort__has_parent = 0; 21int sort__has_parent = 0;
22int sort__has_sym = 0; 22int sort__has_sym = 0;
23int sort__has_dso = 0; 23int sort__has_dso = 0;
24int sort__has_socket = 0;
24enum sort_mode sort__mode = SORT_MODE__NORMAL; 25enum sort_mode sort__mode = SORT_MODE__NORMAL;
25 26
26 27
@@ -328,8 +329,8 @@ static char *get_srcfile(struct hist_entry *e)
328 char *sf, *p; 329 char *sf, *p;
329 struct map *map = e->ms.map; 330 struct map *map = e->ms.map;
330 331
331 sf = get_srcline(map->dso, map__rip_2objdump(map, e->ip), 332 sf = __get_srcline(map->dso, map__rip_2objdump(map, e->ip),
332 e->ms.sym, true); 333 e->ms.sym, false, true);
333 if (!strcmp(sf, SRCLINE_UNKNOWN)) 334 if (!strcmp(sf, SRCLINE_UNKNOWN))
334 return no_srcfile; 335 return no_srcfile;
335 p = strchr(sf, ':'); 336 p = strchr(sf, ':');
@@ -421,6 +422,27 @@ struct sort_entry sort_cpu = {
421 .se_width_idx = HISTC_CPU, 422 .se_width_idx = HISTC_CPU,
422}; 423};
423 424
425/* --sort socket */
426
427static int64_t
428sort__socket_cmp(struct hist_entry *left, struct hist_entry *right)
429{
430 return right->socket - left->socket;
431}
432
433static int hist_entry__socket_snprintf(struct hist_entry *he, char *bf,
434 size_t size, unsigned int width)
435{
436 return repsep_snprintf(bf, size, "%*.*d", width, width-3, he->socket);
437}
438
439struct sort_entry sort_socket = {
440 .se_header = "Socket",
441 .se_cmp = sort__socket_cmp,
442 .se_snprintf = hist_entry__socket_snprintf,
443 .se_width_idx = HISTC_SOCKET,
444};
445
424/* sort keys for branch stacks */ 446/* sort keys for branch stacks */
425 447
426static int64_t 448static int64_t
@@ -633,6 +655,35 @@ static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
633} 655}
634 656
635static int64_t 657static int64_t
658sort__iaddr_cmp(struct hist_entry *left, struct hist_entry *right)
659{
660 uint64_t l = 0, r = 0;
661
662 if (left->mem_info)
663 l = left->mem_info->iaddr.addr;
664 if (right->mem_info)
665 r = right->mem_info->iaddr.addr;
666
667 return (int64_t)(r - l);
668}
669
670static int hist_entry__iaddr_snprintf(struct hist_entry *he, char *bf,
671 size_t size, unsigned int width)
672{
673 uint64_t addr = 0;
674 struct map *map = NULL;
675 struct symbol *sym = NULL;
676
677 if (he->mem_info) {
678 addr = he->mem_info->iaddr.addr;
679 map = he->mem_info->iaddr.map;
680 sym = he->mem_info->iaddr.sym;
681 }
682 return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
683 width);
684}
685
686static int64_t
636sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right) 687sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
637{ 688{
638 struct map *map_l = NULL; 689 struct map *map_l = NULL;
@@ -1055,6 +1106,13 @@ struct sort_entry sort_mem_daddr_sym = {
1055 .se_width_idx = HISTC_MEM_DADDR_SYMBOL, 1106 .se_width_idx = HISTC_MEM_DADDR_SYMBOL,
1056}; 1107};
1057 1108
1109struct sort_entry sort_mem_iaddr_sym = {
1110 .se_header = "Code Symbol",
1111 .se_cmp = sort__iaddr_cmp,
1112 .se_snprintf = hist_entry__iaddr_snprintf,
1113 .se_width_idx = HISTC_MEM_IADDR_SYMBOL,
1114};
1115
1058struct sort_entry sort_mem_daddr_dso = { 1116struct sort_entry sort_mem_daddr_dso = {
1059 .se_header = "Data Object", 1117 .se_header = "Data Object",
1060 .se_cmp = sort__dso_daddr_cmp, 1118 .se_cmp = sort__dso_daddr_cmp,
@@ -1248,6 +1306,7 @@ static struct sort_dimension common_sort_dimensions[] = {
1248 DIM(SORT_SYM, "symbol", sort_sym), 1306 DIM(SORT_SYM, "symbol", sort_sym),
1249 DIM(SORT_PARENT, "parent", sort_parent), 1307 DIM(SORT_PARENT, "parent", sort_parent),
1250 DIM(SORT_CPU, "cpu", sort_cpu), 1308 DIM(SORT_CPU, "cpu", sort_cpu),
1309 DIM(SORT_SOCKET, "socket", sort_socket),
1251 DIM(SORT_SRCLINE, "srcline", sort_srcline), 1310 DIM(SORT_SRCLINE, "srcline", sort_srcline),
1252 DIM(SORT_SRCFILE, "srcfile", sort_srcfile), 1311 DIM(SORT_SRCFILE, "srcfile", sort_srcfile),
1253 DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight), 1312 DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
@@ -1276,6 +1335,7 @@ static struct sort_dimension bstack_sort_dimensions[] = {
1276 1335
1277static struct sort_dimension memory_sort_dimensions[] = { 1336static struct sort_dimension memory_sort_dimensions[] = {
1278 DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym), 1337 DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
1338 DIM(SORT_MEM_IADDR_SYMBOL, "symbol_iaddr", sort_mem_iaddr_sym),
1279 DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso), 1339 DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
1280 DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked), 1340 DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
1281 DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb), 1341 DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
@@ -1517,6 +1577,12 @@ static int __hpp_dimension__add_output(struct hpp_dimension *hd)
1517 return 0; 1577 return 0;
1518} 1578}
1519 1579
1580int hpp_dimension__add_output(unsigned col)
1581{
1582 BUG_ON(col >= PERF_HPP__MAX_INDEX);
1583 return __hpp_dimension__add_output(&hpp_sort_dimensions[col]);
1584}
1585
1520int sort_dimension__add(const char *tok) 1586int sort_dimension__add(const char *tok)
1521{ 1587{
1522 unsigned int i; 1588 unsigned int i;
@@ -1550,6 +1616,8 @@ int sort_dimension__add(const char *tok)
1550 1616
1551 } else if (sd->entry == &sort_dso) { 1617 } else if (sd->entry == &sort_dso) {
1552 sort__has_dso = 1; 1618 sort__has_dso = 1;
1619 } else if (sd->entry == &sort_socket) {
1620 sort__has_socket = 1;
1553 } 1621 }
1554 1622
1555 return __sort_dimension__add(sd); 1623 return __sort_dimension__add(sd);
@@ -1855,8 +1923,6 @@ static int __setup_output_field(void)
1855 if (field_order == NULL) 1923 if (field_order == NULL)
1856 return 0; 1924 return 0;
1857 1925
1858 reset_dimensions();
1859
1860 strp = str = strdup(field_order); 1926 strp = str = strdup(field_order);
1861 if (str == NULL) { 1927 if (str == NULL) {
1862 error("Not enough memory to setup output fields"); 1928 error("Not enough memory to setup output fields");
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 3c2a399f8f5b..31228851e397 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -34,6 +34,7 @@ extern int have_ignore_callees;
34extern int sort__need_collapse; 34extern int sort__need_collapse;
35extern int sort__has_parent; 35extern int sort__has_parent;
36extern int sort__has_sym; 36extern int sort__has_sym;
37extern int sort__has_socket;
37extern enum sort_mode sort__mode; 38extern enum sort_mode sort__mode;
38extern struct sort_entry sort_comm; 39extern struct sort_entry sort_comm;
39extern struct sort_entry sort_dso; 40extern struct sort_entry sort_dso;
@@ -90,6 +91,7 @@ struct hist_entry {
90 struct comm *comm; 91 struct comm *comm;
91 u64 ip; 92 u64 ip;
92 u64 transaction; 93 u64 transaction;
94 s32 socket;
93 s32 cpu; 95 s32 cpu;
94 u8 cpumode; 96 u8 cpumode;
95 97
@@ -172,6 +174,7 @@ enum sort_type {
172 SORT_SYM, 174 SORT_SYM,
173 SORT_PARENT, 175 SORT_PARENT,
174 SORT_CPU, 176 SORT_CPU,
177 SORT_SOCKET,
175 SORT_SRCLINE, 178 SORT_SRCLINE,
176 SORT_SRCFILE, 179 SORT_SRCFILE,
177 SORT_LOCAL_WEIGHT, 180 SORT_LOCAL_WEIGHT,
@@ -198,6 +201,7 @@ enum sort_type {
198 SORT_MEM_LVL, 201 SORT_MEM_LVL,
199 SORT_MEM_SNOOP, 202 SORT_MEM_SNOOP,
200 SORT_MEM_DCACHELINE, 203 SORT_MEM_DCACHELINE,
204 SORT_MEM_IADDR_SYMBOL,
201}; 205};
202 206
203/* 207/*
@@ -230,4 +234,6 @@ void perf_hpp__set_elide(int idx, bool elide);
230int report_parse_ignore_callees_opt(const struct option *opt, const char *arg, int unset); 234int report_parse_ignore_callees_opt(const struct option *opt, const char *arg, int unset);
231 235
232bool is_strict_order(const char *order); 236bool is_strict_order(const char *order);
237
238int hpp_dimension__add_output(unsigned col);
233#endif /* __PERF_SORT_H */ 239#endif /* __PERF_SORT_H */
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index fc08248f08ca..b4db3f48e3b0 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -149,8 +149,11 @@ static void addr2line_cleanup(struct a2l_data *a2l)
149 free(a2l); 149 free(a2l);
150} 150}
151 151
152#define MAX_INLINE_NEST 1024
153
152static int addr2line(const char *dso_name, u64 addr, 154static int addr2line(const char *dso_name, u64 addr,
153 char **file, unsigned int *line, struct dso *dso) 155 char **file, unsigned int *line, struct dso *dso,
156 bool unwind_inlines)
154{ 157{
155 int ret = 0; 158 int ret = 0;
156 struct a2l_data *a2l = dso->a2l; 159 struct a2l_data *a2l = dso->a2l;
@@ -170,6 +173,15 @@ static int addr2line(const char *dso_name, u64 addr,
170 173
171 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); 174 bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l);
172 175
176 if (a2l->found && unwind_inlines) {
177 int cnt = 0;
178
179 while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
180 &a2l->funcname, &a2l->line) &&
181 cnt++ < MAX_INLINE_NEST)
182 ;
183 }
184
173 if (a2l->found && a2l->filename) { 185 if (a2l->found && a2l->filename) {
174 *file = strdup(a2l->filename); 186 *file = strdup(a2l->filename);
175 *line = a2l->line; 187 *line = a2l->line;
@@ -197,7 +209,8 @@ void dso__free_a2l(struct dso *dso)
197 209
198static int addr2line(const char *dso_name, u64 addr, 210static int addr2line(const char *dso_name, u64 addr,
199 char **file, unsigned int *line_nr, 211 char **file, unsigned int *line_nr,
200 struct dso *dso __maybe_unused) 212 struct dso *dso __maybe_unused,
213 bool unwind_inlines __maybe_unused)
201{ 214{
202 FILE *fp; 215 FILE *fp;
203 char cmd[PATH_MAX]; 216 char cmd[PATH_MAX];
@@ -254,8 +267,8 @@ void dso__free_a2l(struct dso *dso __maybe_unused)
254 */ 267 */
255#define A2L_FAIL_LIMIT 123 268#define A2L_FAIL_LIMIT 123
256 269
257char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 270char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
258 bool show_sym) 271 bool show_sym, bool unwind_inlines)
259{ 272{
260 char *file = NULL; 273 char *file = NULL;
261 unsigned line = 0; 274 unsigned line = 0;
@@ -276,7 +289,7 @@ char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
276 if (!strncmp(dso_name, "/tmp/perf-", 10)) 289 if (!strncmp(dso_name, "/tmp/perf-", 10))
277 goto out; 290 goto out;
278 291
279 if (!addr2line(dso_name, addr, &file, &line, dso)) 292 if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines))
280 goto out; 293 goto out;
281 294
282 if (asprintf(&srcline, "%s:%u", 295 if (asprintf(&srcline, "%s:%u",
@@ -310,3 +323,9 @@ void free_srcline(char *srcline)
310 if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) 323 if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
311 free(srcline); 324 free(srcline);
312} 325}
326
327char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
328 bool show_sym)
329{
330 return __get_srcline(dso, addr, sym, show_sym, false);
331}
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 415c359de465..2d9d8306dbd3 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -67,7 +67,7 @@ double rel_stddev_stats(double stddev, double avg)
67bool __perf_evsel_stat__is(struct perf_evsel *evsel, 67bool __perf_evsel_stat__is(struct perf_evsel *evsel,
68 enum perf_stat_evsel_id id) 68 enum perf_stat_evsel_id id)
69{ 69{
70 struct perf_stat *ps = evsel->priv; 70 struct perf_stat_evsel *ps = evsel->priv;
71 71
72 return ps->id == id; 72 return ps->id == id;
73} 73}
@@ -84,7 +84,7 @@ static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
84 84
85void perf_stat_evsel_id_init(struct perf_evsel *evsel) 85void perf_stat_evsel_id_init(struct perf_evsel *evsel)
86{ 86{
87 struct perf_stat *ps = evsel->priv; 87 struct perf_stat_evsel *ps = evsel->priv;
88 int i; 88 int i;
89 89
90 /* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */ 90 /* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
@@ -100,7 +100,7 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
100void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) 100void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
101{ 101{
102 int i; 102 int i;
103 struct perf_stat *ps = evsel->priv; 103 struct perf_stat_evsel *ps = evsel->priv;
104 104
105 for (i = 0; i < 3; i++) 105 for (i = 0; i < 3; i++)
106 init_stats(&ps->res_stats[i]); 106 init_stats(&ps->res_stats[i]);
@@ -110,7 +110,7 @@ void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
110 110
111int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) 111int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
112{ 112{
113 evsel->priv = zalloc(sizeof(struct perf_stat)); 113 evsel->priv = zalloc(sizeof(struct perf_stat_evsel));
114 if (evsel->priv == NULL) 114 if (evsel->priv == NULL)
115 return -ENOMEM; 115 return -ENOMEM;
116 perf_evsel__reset_stat_priv(evsel); 116 perf_evsel__reset_stat_priv(evsel);
@@ -196,7 +196,8 @@ static void zero_per_pkg(struct perf_evsel *counter)
196 memset(counter->per_pkg_mask, 0, MAX_NR_CPUS); 196 memset(counter->per_pkg_mask, 0, MAX_NR_CPUS);
197} 197}
198 198
199static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip) 199static int check_per_pkg(struct perf_evsel *counter,
200 struct perf_counts_values *vals, int cpu, bool *skip)
200{ 201{
201 unsigned long *mask = counter->per_pkg_mask; 202 unsigned long *mask = counter->per_pkg_mask;
202 struct cpu_map *cpus = perf_evsel__cpus(counter); 203 struct cpu_map *cpus = perf_evsel__cpus(counter);
@@ -218,7 +219,18 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
218 counter->per_pkg_mask = mask; 219 counter->per_pkg_mask = mask;
219 } 220 }
220 221
221 s = cpu_map__get_socket(cpus, cpu); 222 /*
223 * we do not consider an event that has not run as a good
224 * instance to mark a package as used (skip=1). Otherwise
225 * we may run into a situation where the first CPU in a package
226 * is not running anything, yet the second is, and this function
227 * would mark the package as used after the first CPU and would
228 * not read the values from the second CPU.
229 */
230 if (!(vals->run && vals->ena))
231 return 0;
232
233 s = cpu_map__get_socket(cpus, cpu, NULL);
222 if (s < 0) 234 if (s < 0)
223 return -1; 235 return -1;
224 236
@@ -235,7 +247,7 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel
235 static struct perf_counts_values zero; 247 static struct perf_counts_values zero;
236 bool skip = false; 248 bool skip = false;
237 249
238 if (check_per_pkg(evsel, cpu, &skip)) { 250 if (check_per_pkg(evsel, count, cpu, &skip)) {
239 pr_err("failed to read per-pkg counter\n"); 251 pr_err("failed to read per-pkg counter\n");
240 return -1; 252 return -1;
241 } 253 }
@@ -260,6 +272,7 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel
260 aggr->ena += count->ena; 272 aggr->ena += count->ena;
261 aggr->run += count->run; 273 aggr->run += count->run;
262 } 274 }
275 case AGGR_UNSET:
263 default: 276 default:
264 break; 277 break;
265 } 278 }
@@ -292,7 +305,7 @@ int perf_stat_process_counter(struct perf_stat_config *config,
292 struct perf_evsel *counter) 305 struct perf_evsel *counter)
293{ 306{
294 struct perf_counts_values *aggr = &counter->counts->aggr; 307 struct perf_counts_values *aggr = &counter->counts->aggr;
295 struct perf_stat *ps = counter->priv; 308 struct perf_stat_evsel *ps = counter->priv;
296 u64 *count = counter->counts->aggr.values; 309 u64 *count = counter->counts->aggr.values;
297 int i, ret; 310 int i, ret;
298 311
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 62448c8175d3..da1d11c4f8c1 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -20,7 +20,7 @@ enum perf_stat_evsel_id {
20 PERF_STAT_EVSEL_ID__MAX, 20 PERF_STAT_EVSEL_ID__MAX,
21}; 21};
22 22
23struct perf_stat { 23struct perf_stat_evsel {
24 struct stats res_stats[3]; 24 struct stats res_stats[3];
25 enum perf_stat_evsel_id id; 25 enum perf_stat_evsel_id id;
26}; 26};
@@ -31,6 +31,7 @@ enum aggr_mode {
31 AGGR_SOCKET, 31 AGGR_SOCKET,
32 AGGR_CORE, 32 AGGR_CORE,
33 AGGR_THREAD, 33 AGGR_THREAD,
34 AGGR_UNSET,
34}; 35};
35 36
36struct perf_stat_config { 37struct perf_stat_config {
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index 4abe23550c73..25671fa16618 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -82,23 +82,22 @@ void strbuf_add(struct strbuf *sb, const void *data, size_t len)
82 strbuf_setlen(sb, sb->len + len); 82 strbuf_setlen(sb, sb->len + len);
83} 83}
84 84
85void strbuf_addf(struct strbuf *sb, const char *fmt, ...) 85void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
86{ 86{
87 int len; 87 int len;
88 va_list ap; 88 va_list ap_saved;
89 89
90 if (!strbuf_avail(sb)) 90 if (!strbuf_avail(sb))
91 strbuf_grow(sb, 64); 91 strbuf_grow(sb, 64);
92 va_start(ap, fmt); 92
93 va_copy(ap_saved, ap);
93 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); 94 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
94 va_end(ap);
95 if (len < 0) 95 if (len < 0)
96 die("your vsnprintf is broken"); 96 die("your vsnprintf is broken");
97 if (len > strbuf_avail(sb)) { 97 if (len > strbuf_avail(sb)) {
98 strbuf_grow(sb, len); 98 strbuf_grow(sb, len);
99 va_start(ap, fmt); 99 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
100 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); 100 va_end(ap_saved);
101 va_end(ap);
102 if (len > strbuf_avail(sb)) { 101 if (len > strbuf_avail(sb)) {
103 die("this should not happen, your vsnprintf is broken"); 102 die("this should not happen, your vsnprintf is broken");
104 } 103 }
@@ -106,6 +105,15 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
106 strbuf_setlen(sb, sb->len + len); 105 strbuf_setlen(sb, sb->len + len);
107} 106}
108 107
108void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
109{
110 va_list ap;
111
112 va_start(ap, fmt);
113 strbuf_addv(sb, fmt, ap);
114 va_end(ap);
115}
116
109ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint) 117ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
110{ 118{
111 size_t oldlen = sb->len; 119 size_t oldlen = sb->len;
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index 436ac319f6c7..529f2f035249 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -39,6 +39,7 @@
39 */ 39 */
40 40
41#include <assert.h> 41#include <assert.h>
42#include <stdarg.h>
42 43
43extern char strbuf_slopbuf[]; 44extern char strbuf_slopbuf[];
44struct strbuf { 45struct strbuf {
@@ -85,6 +86,7 @@ static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
85 86
86__attribute__((format(printf,2,3))) 87__attribute__((format(printf,2,3)))
87extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); 88extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
89extern void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap);
88 90
89/* XXX: if read fails, any partial read is undone */ 91/* XXX: if read fails, any partial read is undone */
90extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 92extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 53bb5f59ec58..475d88d0a1c9 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -38,7 +38,7 @@ static inline char *bfd_demangle(void __maybe_unused *v,
38#endif 38#endif
39 39
40#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT 40#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
41int elf_getphdrnum(Elf *elf, size_t *dst) 41static int elf_getphdrnum(Elf *elf, size_t *dst)
42{ 42{
43 GElf_Ehdr gehdr; 43 GElf_Ehdr gehdr;
44 GElf_Ehdr *ehdr; 44 GElf_Ehdr *ehdr;
@@ -1271,8 +1271,6 @@ out_close:
1271static int kcore__init(struct kcore *kcore, char *filename, int elfclass, 1271static int kcore__init(struct kcore *kcore, char *filename, int elfclass,
1272 bool temp) 1272 bool temp)
1273{ 1273{
1274 GElf_Ehdr *ehdr;
1275
1276 kcore->elfclass = elfclass; 1274 kcore->elfclass = elfclass;
1277 1275
1278 if (temp) 1276 if (temp)
@@ -1289,9 +1287,7 @@ static int kcore__init(struct kcore *kcore, char *filename, int elfclass,
1289 if (!gelf_newehdr(kcore->elf, elfclass)) 1287 if (!gelf_newehdr(kcore->elf, elfclass))
1290 goto out_end; 1288 goto out_end;
1291 1289
1292 ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr); 1290 memset(&kcore->ehdr, 0, sizeof(GElf_Ehdr));
1293 if (!ehdr)
1294 goto out_end;
1295 1291
1296 return 0; 1292 return 0;
1297 1293
@@ -1348,23 +1344,18 @@ static int kcore__copy_hdr(struct kcore *from, struct kcore *to, size_t count)
1348static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset, 1344static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset,
1349 u64 addr, u64 len) 1345 u64 addr, u64 len)
1350{ 1346{
1351 GElf_Phdr gphdr; 1347 GElf_Phdr phdr = {
1352 GElf_Phdr *phdr; 1348 .p_type = PT_LOAD,
1353 1349 .p_flags = PF_R | PF_W | PF_X,
1354 phdr = gelf_getphdr(kcore->elf, idx, &gphdr); 1350 .p_offset = offset,
1355 if (!phdr) 1351 .p_vaddr = addr,
1356 return -1; 1352 .p_paddr = 0,
1357 1353 .p_filesz = len,
1358 phdr->p_type = PT_LOAD; 1354 .p_memsz = len,
1359 phdr->p_flags = PF_R | PF_W | PF_X; 1355 .p_align = page_size,
1360 phdr->p_offset = offset; 1356 };
1361 phdr->p_vaddr = addr; 1357
1362 phdr->p_paddr = 0; 1358 if (!gelf_update_phdr(kcore->elf, idx, &phdr))
1363 phdr->p_filesz = len;
1364 phdr->p_memsz = len;
1365 phdr->p_align = page_size;
1366
1367 if (!gelf_update_phdr(kcore->elf, idx, phdr))
1368 return -1; 1359 return -1;
1369 1360
1370 return 0; 1361 return 0;
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index fd8477cacf88..48906333a858 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -337,7 +337,7 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
337 symbol_filter_t filter __maybe_unused, 337 symbol_filter_t filter __maybe_unused,
338 int kmodule __maybe_unused) 338 int kmodule __maybe_unused)
339{ 339{
340 unsigned char *build_id[BUILD_ID_SIZE]; 340 unsigned char build_id[BUILD_ID_SIZE];
341 int ret; 341 int ret;
342 342
343 ret = fd__is_64_bit(ss->fd); 343 ret = fd__is_64_bit(ss->fd);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 1f97ffb158a6..b4cc7662677e 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -624,7 +624,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
624 * symbols, setting length to 0, and rely on 624 * symbols, setting length to 0, and rely on
625 * symbols__fixup_end() to fix it up. 625 * symbols__fixup_end() to fix it up.
626 */ 626 */
627 sym = symbol__new(start, 0, kallsyms2elf_type(type), name); 627 sym = symbol__new(start, 0, kallsyms2elf_binding(type), name);
628 if (sym == NULL) 628 if (sym == NULL)
629 return -ENOMEM; 629 return -ENOMEM;
630 /* 630 /*
@@ -680,7 +680,7 @@ static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
680 pos->start -= curr_map->start - curr_map->pgoff; 680 pos->start -= curr_map->start - curr_map->pgoff;
681 if (pos->end) 681 if (pos->end)
682 pos->end -= curr_map->start - curr_map->pgoff; 682 pos->end -= curr_map->start - curr_map->pgoff;
683 if (curr_map != map) { 683 if (curr_map->dso != map->dso) {
684 rb_erase_init(&pos->rb_node, root); 684 rb_erase_init(&pos->rb_node, root);
685 symbols__insert( 685 symbols__insert(
686 &curr_map->dso->symbols[curr_map->type], 686 &curr_map->dso->symbols[curr_map->type],
@@ -1406,6 +1406,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1406 struct symsrc ss_[2]; 1406 struct symsrc ss_[2];
1407 struct symsrc *syms_ss = NULL, *runtime_ss = NULL; 1407 struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
1408 bool kmod; 1408 bool kmod;
1409 unsigned char build_id[BUILD_ID_SIZE];
1409 1410
1410 pthread_mutex_lock(&dso->lock); 1411 pthread_mutex_lock(&dso->lock);
1411 1412
@@ -1461,6 +1462,14 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1461 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE || 1462 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
1462 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; 1463 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
1463 1464
1465
1466 /*
1467 * Read the build id if possible. This is required for
1468 * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work
1469 */
1470 if (filename__read_build_id(dso->name, build_id, BUILD_ID_SIZE) > 0)
1471 dso__set_build_id(dso, build_id);
1472
1464 /* 1473 /*
1465 * Iterate over candidate debug images. 1474 * Iterate over candidate debug images.
1466 * Keep track of "interesting" ones (those which have a symtab, dynsym, 1475 * Keep track of "interesting" ones (those which have a symtab, dynsym,
@@ -1607,6 +1616,15 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1607 int i, err = 0; 1616 int i, err = 0;
1608 char *filename = NULL; 1617 char *filename = NULL;
1609 1618
1619 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1620 vmlinux_path__nr_entries + 1);
1621
1622 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1623 err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter);
1624 if (err > 0)
1625 goto out;
1626 }
1627
1610 if (!symbol_conf.ignore_vmlinux_buildid) 1628 if (!symbol_conf.ignore_vmlinux_buildid)
1611 filename = dso__build_id_filename(dso, NULL, 0); 1629 filename = dso__build_id_filename(dso, NULL, 0);
1612 if (filename != NULL) { 1630 if (filename != NULL) {
@@ -1615,15 +1633,6 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1615 goto out; 1633 goto out;
1616 free(filename); 1634 free(filename);
1617 } 1635 }
1618
1619 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1620 vmlinux_path__nr_entries + 1);
1621
1622 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1623 err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter);
1624 if (err > 0)
1625 break;
1626 }
1627out: 1636out:
1628 return err; 1637 return err;
1629} 1638}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 440ba8ae888f..40073c60b83d 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -191,6 +191,7 @@ struct addr_location {
191 u8 filtered; 191 u8 filtered;
192 u8 cpumode; 192 u8 cpumode;
193 s32 cpu; 193 s32 cpu;
194 s32 socket;
194}; 195};
195 196
196struct symsrc { 197struct symsrc {
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 22245986e59e..d995743cb673 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -38,7 +38,7 @@
38 38
39#include "../perf.h" 39#include "../perf.h"
40#include "trace-event.h" 40#include "trace-event.h"
41#include <api/fs/debugfs.h> 41#include <api/fs/tracing_path.h>
42#include "evsel.h" 42#include "evsel.h"
43#include "debug.h" 43#include "debug.h"
44 44
diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c
index b90e646c7a91..802bb868d446 100644
--- a/tools/perf/util/trace-event.c
+++ b/tools/perf/util/trace-event.c
@@ -7,7 +7,9 @@
7#include <sys/stat.h> 7#include <sys/stat.h>
8#include <fcntl.h> 8#include <fcntl.h>
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/err.h>
10#include <traceevent/event-parse.h> 11#include <traceevent/event-parse.h>
12#include <api/fs/tracing_path.h>
11#include "trace-event.h" 13#include "trace-event.h"
12#include "machine.h" 14#include "machine.h"
13#include "util.h" 15#include "util.h"
@@ -65,6 +67,9 @@ void trace_event__cleanup(struct trace_event *t)
65 pevent_free(t->pevent); 67 pevent_free(t->pevent);
66} 68}
67 69
70/*
71 * Returns pointer with encoded error via <linux/err.h> interface.
72 */
68static struct event_format* 73static struct event_format*
69tp_format(const char *sys, const char *name) 74tp_format(const char *sys, const char *name)
70{ 75{
@@ -73,12 +78,14 @@ tp_format(const char *sys, const char *name)
73 char path[PATH_MAX]; 78 char path[PATH_MAX];
74 size_t size; 79 size_t size;
75 char *data; 80 char *data;
81 int err;
76 82
77 scnprintf(path, PATH_MAX, "%s/%s/%s/format", 83 scnprintf(path, PATH_MAX, "%s/%s/%s/format",
78 tracing_events_path, sys, name); 84 tracing_events_path, sys, name);
79 85
80 if (filename__read_str(path, &data, &size)) 86 err = filename__read_str(path, &data, &size);
81 return NULL; 87 if (err)
88 return ERR_PTR(err);
82 89
83 pevent_parse_format(pevent, &event, data, size, sys); 90 pevent_parse_format(pevent, &event, data, size, sys);
84 91
@@ -86,11 +93,14 @@ tp_format(const char *sys, const char *name)
86 return event; 93 return event;
87} 94}
88 95
96/*
97 * Returns pointer with encoded error via <linux/err.h> interface.
98 */
89struct event_format* 99struct event_format*
90trace_event__tp_format(const char *sys, const char *name) 100trace_event__tp_format(const char *sys, const char *name)
91{ 101{
92 if (!tevent_initialized && trace_event__init2()) 102 if (!tevent_initialized && trace_event__init2())
93 return NULL; 103 return ERR_PTR(-ENOMEM);
94 104
95 return tp_format(sys, name); 105 return tp_format(sys, name);
96} 106}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index da6cc4cc2a4f..b85ee55cca0c 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -78,6 +78,8 @@ struct scripting_ops {
78 int (*generate_script) (struct pevent *pevent, const char *outfile); 78 int (*generate_script) (struct pevent *pevent, const char *outfile);
79}; 79};
80 80
81extern unsigned int scripting_max_stack;
82
81int script_spec_register(const char *spec, struct scripting_ops *ops); 83int script_spec_register(const char *spec, struct scripting_ops *ops);
82 84
83void setup_perl_scripting(void); 85void setup_perl_scripting(void);
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 4c00507ee3fd..c83832b555e5 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -330,6 +330,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
330 struct map *map; 330 struct map *map;
331 unw_dyn_info_t di; 331 unw_dyn_info_t di;
332 u64 table_data, segbase, fde_count; 332 u64 table_data, segbase, fde_count;
333 int ret = -EINVAL;
333 334
334 map = find_map(ip, ui); 335 map = find_map(ip, ui);
335 if (!map || !map->dso) 336 if (!map || !map->dso)
@@ -348,29 +349,33 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
348 di.u.rti.table_data = map->start + table_data; 349 di.u.rti.table_data = map->start + table_data;
349 di.u.rti.table_len = fde_count * sizeof(struct table_entry) 350 di.u.rti.table_len = fde_count * sizeof(struct table_entry)
350 / sizeof(unw_word_t); 351 / sizeof(unw_word_t);
351 return dwarf_search_unwind_table(as, ip, &di, pi, 352 ret = dwarf_search_unwind_table(as, ip, &di, pi,
352 need_unwind_info, arg); 353 need_unwind_info, arg);
353 } 354 }
354 355
355#ifndef NO_LIBUNWIND_DEBUG_FRAME 356#ifndef NO_LIBUNWIND_DEBUG_FRAME
356 /* Check the .debug_frame section for unwinding info */ 357 /* Check the .debug_frame section for unwinding info */
357 if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { 358 if (ret < 0 &&
359 !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
358 int fd = dso__data_get_fd(map->dso, ui->machine); 360 int fd = dso__data_get_fd(map->dso, ui->machine);
359 int is_exec = elf_is_exec(fd, map->dso->name); 361 int is_exec = elf_is_exec(fd, map->dso->name);
360 unw_word_t base = is_exec ? 0 : map->start; 362 unw_word_t base = is_exec ? 0 : map->start;
363 const char *symfile;
361 364
362 if (fd >= 0) 365 if (fd >= 0)
363 dso__data_put_fd(map->dso); 366 dso__data_put_fd(map->dso);
364 367
368 symfile = map->dso->symsrc_filename ?: map->dso->name;
369
365 memset(&di, 0, sizeof(di)); 370 memset(&di, 0, sizeof(di));
366 if (dwarf_find_debug_frame(0, &di, ip, base, map->dso->name, 371 if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
367 map->start, map->end)) 372 map->start, map->end))
368 return dwarf_search_unwind_table(as, ip, &di, pi, 373 return dwarf_search_unwind_table(as, ip, &di, pi,
369 need_unwind_info, arg); 374 need_unwind_info, arg);
370 } 375 }
371#endif 376#endif
372 377
373 return -EINVAL; 378 return ret;
374} 379}
375 380
376static int access_fpreg(unw_addr_space_t __maybe_unused as, 381static int access_fpreg(unw_addr_space_t __maybe_unused as,
@@ -461,7 +466,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as,
461 if (ret) { 466 if (ret) {
462 pr_debug("unwind: access_mem %p not inside range" 467 pr_debug("unwind: access_mem %p not inside range"
463 " 0x%" PRIx64 "-0x%" PRIx64 "\n", 468 " 0x%" PRIx64 "-0x%" PRIx64 "\n",
464 (void *) addr, start, end); 469 (void *) (uintptr_t) addr, start, end);
465 *valp = 0; 470 *valp = 0;
466 return ret; 471 return ret;
467 } 472 }
@@ -471,7 +476,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as,
471 offset = addr - start; 476 offset = addr - start;
472 *valp = *(unw_word_t *)&stack->data[offset]; 477 *valp = *(unw_word_t *)&stack->data[offset];
473 pr_debug("unwind: access_mem addr %p val %lx, offset %d\n", 478 pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
474 (void *) addr, (unsigned long)*valp, offset); 479 (void *) (uintptr_t) addr, (unsigned long)*valp, offset);
475 return 0; 480 return 0;
476} 481}
477 482
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c
index 4007aca8e0ca..6adfa18cdd4e 100644
--- a/tools/perf/util/usage.c
+++ b/tools/perf/util/usage.c
@@ -50,6 +50,11 @@ void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN)
50 die_routine = routine; 50 die_routine = routine;
51} 51}
52 52
53void set_warning_routine(void (*routine)(const char *err, va_list params))
54{
55 warn_routine = routine;
56}
57
53void usage(const char *err) 58void usage(const char *err)
54{ 59{
55 usage_routine(err); 60 usage_routine(err);
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 7acafb3c5592..cd12c25e4ea4 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -17,7 +17,7 @@
17#include "callchain.h" 17#include "callchain.h"
18 18
19struct callchain_param callchain_param = { 19struct callchain_param callchain_param = {
20 .mode = CHAIN_GRAPH_REL, 20 .mode = CHAIN_GRAPH_ABS,
21 .min_percent = 0.5, 21 .min_percent = 0.5,
22 .order = ORDER_CALLEE, 22 .order = ORDER_CALLEE,
23 .key = CCKEY_FUNCTION 23 .key = CCKEY_FUNCTION
@@ -34,9 +34,6 @@ bool test_attr__enabled;
34bool perf_host = true; 34bool perf_host = true;
35bool perf_guest = false; 35bool perf_guest = false;
36 36
37char tracing_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing";
38char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events";
39
40void event_attr_init(struct perf_event_attr *attr) 37void event_attr_init(struct perf_event_attr *attr)
41{ 38{
42 if (!perf_host) 39 if (!perf_host)
@@ -390,73 +387,6 @@ void set_term_quiet_input(struct termios *old)
390 tcsetattr(0, TCSANOW, &tc); 387 tcsetattr(0, TCSANOW, &tc);
391} 388}
392 389
393static void set_tracing_events_path(const char *tracing, const char *mountpoint)
394{
395 snprintf(tracing_path, sizeof(tracing_path), "%s/%s",
396 mountpoint, tracing);
397 snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s",
398 mountpoint, tracing, "events");
399}
400
401static const char *__perf_tracefs_mount(const char *mountpoint)
402{
403 const char *mnt;
404
405 mnt = tracefs_mount(mountpoint);
406 if (!mnt)
407 return NULL;
408
409 set_tracing_events_path("", mnt);
410
411 return mnt;
412}
413
414static const char *__perf_debugfs_mount(const char *mountpoint)
415{
416 const char *mnt;
417
418 mnt = debugfs_mount(mountpoint);
419 if (!mnt)
420 return NULL;
421
422 set_tracing_events_path("tracing/", mnt);
423
424 return mnt;
425}
426
427const char *perf_debugfs_mount(const char *mountpoint)
428{
429 const char *mnt;
430
431 mnt = __perf_tracefs_mount(mountpoint);
432 if (mnt)
433 return mnt;
434
435 mnt = __perf_debugfs_mount(mountpoint);
436
437 return mnt;
438}
439
440void perf_debugfs_set_path(const char *mntpt)
441{
442 set_tracing_events_path("tracing/", mntpt);
443}
444
445char *get_tracing_file(const char *name)
446{
447 char *file;
448
449 if (asprintf(&file, "%s/%s", tracing_path, name) < 0)
450 return NULL;
451
452 return file;
453}
454
455void put_tracing_file(char *file)
456{
457 free(file);
458}
459
460int parse_nsec_time(const char *str, u64 *ptime) 390int parse_nsec_time(const char *str, u64 *ptime)
461{ 391{
462 u64 time_sec, time_nsec; 392 u64 time_sec, time_nsec;
@@ -709,7 +639,7 @@ bool find_process(const char *name)
709 639
710 dir = opendir(procfs__mountpoint()); 640 dir = opendir(procfs__mountpoint());
711 if (!dir) 641 if (!dir)
712 return -1; 642 return false;
713 643
714 /* Walk through the directory. */ 644 /* Walk through the directory. */
715 while (ret && (d = readdir(dir)) != NULL) { 645 while (ret && (d = readdir(dir)) != NULL) {
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 291be1d84bc3..4cfb913aa9e0 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -74,8 +74,7 @@
74#include <linux/magic.h> 74#include <linux/magic.h>
75#include <linux/types.h> 75#include <linux/types.h>
76#include <sys/ttydefaults.h> 76#include <sys/ttydefaults.h>
77#include <api/fs/debugfs.h> 77#include <api/fs/tracing_path.h>
78#include <api/fs/tracefs.h>
79#include <termios.h> 78#include <termios.h>
80#include <linux/bitops.h> 79#include <linux/bitops.h>
81#include <termios.h> 80#include <termios.h>
@@ -83,12 +82,6 @@
83extern const char *graph_line; 82extern const char *graph_line;
84extern const char *graph_dotted_line; 83extern const char *graph_dotted_line;
85extern char buildid_dir[]; 84extern char buildid_dir[];
86extern char tracing_path[];
87extern char tracing_events_path[];
88extern void perf_debugfs_set_path(const char *mountpoint);
89const char *perf_debugfs_mount(const char *mountpoint);
90char *get_tracing_file(const char *name);
91void put_tracing_file(char *file);
92 85
93/* On most systems <limits.h> would have given us this, but 86/* On most systems <limits.h> would have given us this, but
94 * not on some systems (e.g. GNU/Hurd). 87 * not on some systems (e.g. GNU/Hurd).
@@ -152,6 +145,7 @@ extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)))
152 145
153 146
154extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); 147extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
148extern void set_warning_routine(void (*routine)(const char *err, va_list params));
155 149
156extern int prefixcmp(const char *str, const char *prefix); 150extern int prefixcmp(const char *str, const char *prefix);
157extern void set_buildid_dir(const char *dir); 151extern void set_buildid_dir(const char *dir);
@@ -321,6 +315,8 @@ struct symbol;
321extern bool srcline_full_filename; 315extern bool srcline_full_filename;
322char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 316char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
323 bool show_sym); 317 bool show_sym);
318char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
319 bool show_sym, bool unwind_inlines);
324void free_srcline(char *srcline); 320void free_srcline(char *srcline);
325 321
326int filename__read_str(const char *filename, char **buf, size_t *sizep); 322int filename__read_str(const char *filename, char **buf, size_t *sizep);