Merge tag 'perf-urgent-for-mingo-4.19-20180903' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent

Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

Kernel:

- Modify breakpoint fixes (Jiri Olsa)

perf annotate:

- Fix parsing aarch64 branch instructions after objdump update (Kim Phillips)

- Fix parsing indirect calls in 'perf annotate' (Martin Liška)

perf probe:

- Ignore SyS symbols irrespective of endianness on PowerPC (Sandipan Das)

perf trace:

- Fix include path for asm-generic/unistd.h on arm64 (Kim Phillips)

Core libraries:

- Fix potential null pointer dereference in perf_evsel__new_idx() (Hisao Tanabe)

- Use fixed size string for comms instead of scanf("%m"), that is
not present in the bionic libc and leads to a crash (Chris Phlipot)

- Fix bad memory access in trace info on 32-bit systems, we were reading
8 bytes from a 4-byte long variable when saving the command line in the
perf.data file. (Chris Phlipot)

Build system:

- Streamline bpf examples and headers installation, clarifying
some install messages. (Arnaldo Carvalho de Melo)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

Changed files
+282 -39
kernel
tools
+3 -8
kernel/events/core.c
··· 2867 2867 _perf_event_disable(bp); 2868 2868 2869 2869 err = modify_user_hw_breakpoint_check(bp, attr, true); 2870 - if (err) { 2871 - if (!bp->attr.disabled) 2872 - _perf_event_enable(bp); 2873 2870 2874 - return err; 2875 - } 2876 - 2877 - if (!attr->disabled) 2871 + if (!bp->attr.disabled) 2878 2872 _perf_event_enable(bp); 2879 - return 0; 2873 + 2874 + return err; 2880 2875 } 2881 2876 2882 2877 static int perf_event_modify_attr(struct perf_event *event,
+6 -7
kernel/events/hw_breakpoint.c
··· 509 509 */ 510 510 int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr) 511 511 { 512 + int err; 513 + 512 514 /* 513 515 * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it 514 516 * will not be possible to raise IPIs that invoke __perf_event_disable. ··· 522 520 else 523 521 perf_event_disable(bp); 524 522 525 - if (!attr->disabled) { 526 - int err = modify_user_hw_breakpoint_check(bp, attr, false); 523 + err = modify_user_hw_breakpoint_check(bp, attr, false); 527 524 528 - if (err) 529 - return err; 525 + if (!bp->attr.disabled) 530 526 perf_event_enable(bp); 531 - bp->attr.disabled = 0; 532 - } 533 - return 0; 527 + 528 + return err; 534 529 } 535 530 EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint); 536 531
+6 -8
tools/perf/Makefile.perf
··· 777 777 $(call QUIET_INSTALL, libexec) \ 778 778 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 779 779 ifndef NO_LIBBPF 780 - $(call QUIET_INSTALL, lib) \ 781 - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf' 782 - $(call QUIET_INSTALL, include/bpf) \ 783 - $(INSTALL) include/bpf/*.h '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf' 784 - $(call QUIET_INSTALL, lib) \ 785 - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 786 - $(call QUIET_INSTALL, examples/bpf) \ 787 - $(INSTALL) examples/bpf/*.c '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 780 + $(call QUIET_INSTALL, bpf-headers) \ 781 + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \ 782 + $(INSTALL) include/bpf/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf' 783 + $(call QUIET_INSTALL, bpf-examples) \ 784 + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'; \ 785 + $(INSTALL) examples/bpf/*.c -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf' 788 786 endif 789 787 $(call QUIET_INSTALL, perf-archive) \ 790 788 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+3 -2
tools/perf/arch/arm64/Makefile
··· 11 11 12 12 out := $(OUTPUT)arch/arm64/include/generated/asm 13 13 header := $(out)/syscalls.c 14 - sysdef := $(srctree)/tools/include/uapi/asm-generic/unistd.h 14 + incpath := $(srctree)/tools 15 + sysdef := $(srctree)/tools/arch/arm64/include/uapi/asm/unistd.h 15 16 sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/ 16 17 systbl := $(sysprf)/mksyscalltbl 17 18 ··· 20 19 _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') 21 20 22 21 $(header): $(sysdef) $(systbl) 23 - $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(sysdef) > $@ 22 + $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@ 24 23 25 24 clean:: 26 25 $(call QUIET_CLEAN, arm64) $(RM) $(header)
+3 -3
tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
··· 11 11 12 12 gcc=$1 13 13 hostcc=$2 14 - input=$3 14 + incpath=$3 15 + input=$4 15 16 16 17 if ! test -r $input; then 17 18 echo "Could not read input file" >&2 ··· 29 28 30 29 cat <<-_EoHEADER 31 30 #include <stdio.h> 32 - #define __ARCH_WANT_RENAMEAT 33 31 #include "$input" 34 32 int main(int argc, char *argv[]) 35 33 { ··· 42 42 printf "%s\n" " printf(\"#define SYSCALLTBL_ARM64_MAX_ID %d\\n\", __NR_$last_sc);" 43 43 printf "}\n" 44 44 45 - } | $hostcc -o $create_table_exe -x c - 45 + } | $hostcc -I $incpath/include/uapi -o $create_table_exe -x c - 46 46 47 47 $create_table_exe 48 48
+3 -1
tools/perf/arch/powerpc/util/sym-handling.c
··· 22 22 23 23 #endif 24 24 25 - #if !defined(_CALL_ELF) || _CALL_ELF != 2 26 25 int arch__choose_best_symbol(struct symbol *syma, 27 26 struct symbol *symb __maybe_unused) 28 27 { 29 28 char *sym = syma->name; 30 29 30 + #if !defined(_CALL_ELF) || _CALL_ELF != 2 31 31 /* Skip over any initial dot */ 32 32 if (*sym == '.') 33 33 sym++; 34 + #endif 34 35 35 36 /* Avoid "SyS" kernel syscall aliases */ 36 37 if (strlen(sym) >= 3 && !strncmp(sym, "SyS", 3)) ··· 42 41 return SYMBOL_A; 43 42 } 44 43 44 + #if !defined(_CALL_ELF) || _CALL_ELF != 2 45 45 /* Allow matching against dot variants */ 46 46 int arch__compare_symbol_names(const char *namea, const char *nameb) 47 47 {
+1
tools/perf/arch/x86/include/arch-tests.h
··· 9 9 int test__rdpmc(struct test *test __maybe_unused, int subtest); 10 10 int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest); 11 11 int test__insn_x86(struct test *test __maybe_unused, int subtest); 12 + int test__bp_modify(struct test *test, int subtest); 12 13 13 14 #ifdef HAVE_DWARF_UNWIND_SUPPORT 14 15 struct thread;
+1
tools/perf/arch/x86/tests/Build
··· 5 5 libperf-y += rdpmc.o 6 6 libperf-y += perf-time-to-tsc.o 7 7 libperf-$(CONFIG_AUXTRACE) += insn-x86.o 8 + libperf-$(CONFIG_X86_64) += bp-modify.o
+6
tools/perf/arch/x86/tests/arch-tests.c
··· 24 24 .func = test__insn_x86, 25 25 }, 26 26 #endif 27 + #if defined(__x86_64__) 28 + { 29 + .desc = "x86 bp modify", 30 + .func = test__bp_modify, 31 + }, 32 + #endif 27 33 { 28 34 .func = NULL, 29 35 },
+213
tools/perf/arch/x86/tests/bp-modify.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/compiler.h> 3 + #include <sys/types.h> 4 + #include <sys/wait.h> 5 + #include <sys/user.h> 6 + #include <syscall.h> 7 + #include <unistd.h> 8 + #include <stdio.h> 9 + #include <stdlib.h> 10 + #include <sys/ptrace.h> 11 + #include <asm/ptrace.h> 12 + #include <errno.h> 13 + #include "debug.h" 14 + #include "tests/tests.h" 15 + #include "arch-tests.h" 16 + 17 + static noinline int bp_1(void) 18 + { 19 + pr_debug("in %s\n", __func__); 20 + return 0; 21 + } 22 + 23 + static noinline int bp_2(void) 24 + { 25 + pr_debug("in %s\n", __func__); 26 + return 0; 27 + } 28 + 29 + static int spawn_child(void) 30 + { 31 + int child = fork(); 32 + 33 + if (child == 0) { 34 + /* 35 + * The child sets itself for as tracee and 36 + * waits in signal for parent to trace it, 37 + * then it calls bp_1 and quits. 38 + */ 39 + int err = ptrace(PTRACE_TRACEME, 0, NULL, NULL); 40 + 41 + if (err) { 42 + pr_debug("failed to PTRACE_TRACEME\n"); 43 + exit(1); 44 + } 45 + 46 + raise(SIGCONT); 47 + bp_1(); 48 + exit(0); 49 + } 50 + 51 + return child; 52 + } 53 + 54 + /* 55 + * This tests creates HW breakpoint, tries to 56 + * change it and checks it was properly changed. 57 + */ 58 + static int bp_modify1(void) 59 + { 60 + pid_t child; 61 + int status; 62 + unsigned long rip = 0, dr7 = 1; 63 + 64 + child = spawn_child(); 65 + 66 + waitpid(child, &status, 0); 67 + if (WIFEXITED(status)) { 68 + pr_debug("tracee exited prematurely 1\n"); 69 + return TEST_FAIL; 70 + } 71 + 72 + /* 73 + * The parent does following steps: 74 + * - creates a new breakpoint (id 0) for bp_2 function 75 + * - changes that breakponit to bp_1 function 76 + * - waits for the breakpoint to hit and checks 77 + * it has proper rip of bp_1 function 78 + * - detaches the child 79 + */ 80 + if (ptrace(PTRACE_POKEUSER, child, 81 + offsetof(struct user, u_debugreg[0]), bp_2)) { 82 + pr_debug("failed to set breakpoint, 1st time: %s\n", 83 + strerror(errno)); 84 + goto out; 85 + } 86 + 87 + if (ptrace(PTRACE_POKEUSER, child, 88 + offsetof(struct user, u_debugreg[0]), bp_1)) { 89 + pr_debug("failed to set breakpoint, 2nd time: %s\n", 90 + strerror(errno)); 91 + goto out; 92 + } 93 + 94 + if (ptrace(PTRACE_POKEUSER, child, 95 + offsetof(struct user, u_debugreg[7]), dr7)) { 96 + pr_debug("failed to set dr7: %s\n", strerror(errno)); 97 + goto out; 98 + } 99 + 100 + if (ptrace(PTRACE_CONT, child, NULL, NULL)) { 101 + pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno)); 102 + goto out; 103 + } 104 + 105 + waitpid(child, &status, 0); 106 + if (WIFEXITED(status)) { 107 + pr_debug("tracee exited prematurely 2\n"); 108 + return TEST_FAIL; 109 + } 110 + 111 + rip = ptrace(PTRACE_PEEKUSER, child, 112 + offsetof(struct user_regs_struct, rip), NULL); 113 + if (rip == (unsigned long) -1) { 114 + pr_debug("failed to PTRACE_PEEKUSER: %s\n", 115 + strerror(errno)); 116 + goto out; 117 + } 118 + 119 + pr_debug("rip %lx, bp_1 %p\n", rip, bp_1); 120 + 121 + out: 122 + if (ptrace(PTRACE_DETACH, child, NULL, NULL)) { 123 + pr_debug("failed to PTRACE_DETACH: %s", strerror(errno)); 124 + return TEST_FAIL; 125 + } 126 + 127 + return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; 128 + } 129 + 130 + /* 131 + * This tests creates HW breakpoint, tries to 132 + * change it to bogus value and checks the original 133 + * breakpoint is hit. 134 + */ 135 + static int bp_modify2(void) 136 + { 137 + pid_t child; 138 + int status; 139 + unsigned long rip = 0, dr7 = 1; 140 + 141 + child = spawn_child(); 142 + 143 + waitpid(child, &status, 0); 144 + if (WIFEXITED(status)) { 145 + pr_debug("tracee exited prematurely 1\n"); 146 + return TEST_FAIL; 147 + } 148 + 149 + /* 150 + * The parent does following steps: 151 + * - creates a new breakpoint (id 0) for bp_1 function 152 + * - tries to change that breakpoint to (-1) address 153 + * - waits for the breakpoint to hit and checks 154 + * it has proper rip of bp_1 function 155 + * - detaches the child 156 + */ 157 + if (ptrace(PTRACE_POKEUSER, child, 158 + offsetof(struct user, u_debugreg[0]), bp_1)) { 159 + pr_debug("failed to set breakpoint: %s\n", 160 + strerror(errno)); 161 + goto out; 162 + } 163 + 164 + if (ptrace(PTRACE_POKEUSER, child, 165 + offsetof(struct user, u_debugreg[7]), dr7)) { 166 + pr_debug("failed to set dr7: %s\n", strerror(errno)); 167 + goto out; 168 + } 169 + 170 + if (!ptrace(PTRACE_POKEUSER, child, 171 + offsetof(struct user, u_debugreg[0]), (unsigned long) (-1))) { 172 + pr_debug("failed, breakpoint set to bogus address\n"); 173 + goto out; 174 + } 175 + 176 + if (ptrace(PTRACE_CONT, child, NULL, NULL)) { 177 + pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno)); 178 + goto out; 179 + } 180 + 181 + waitpid(child, &status, 0); 182 + if (WIFEXITED(status)) { 183 + pr_debug("tracee exited prematurely 2\n"); 184 + return TEST_FAIL; 185 + } 186 + 187 + rip = ptrace(PTRACE_PEEKUSER, child, 188 + offsetof(struct user_regs_struct, rip), NULL); 189 + if (rip == (unsigned long) -1) { 190 + pr_debug("failed to PTRACE_PEEKUSER: %s\n", 191 + strerror(errno)); 192 + goto out; 193 + } 194 + 195 + pr_debug("rip %lx, bp_1 %p\n", rip, bp_1); 196 + 197 + out: 198 + if (ptrace(PTRACE_DETACH, child, NULL, NULL)) { 199 + pr_debug("failed to PTRACE_DETACH: %s", strerror(errno)); 200 + return TEST_FAIL; 201 + } 202 + 203 + return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; 204 + } 205 + 206 + int test__bp_modify(struct test *test __maybe_unused, 207 + int subtest __maybe_unused) 208 + { 209 + TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1()); 210 + TEST_ASSERT_VAL("modify test 2 failed\n", !bp_modify2()); 211 + 212 + return 0; 213 + }
+29 -3
tools/perf/util/annotate.c
··· 246 246 247 247 indirect_call: 248 248 tok = strchr(endptr, '*'); 249 - if (tok != NULL) 250 - ops->target.addr = strtoull(tok + 1, NULL, 16); 249 + if (tok != NULL) { 250 + endptr++; 251 + 252 + /* Indirect call can use a non-rip register and offset: callq *0x8(%rbx). 253 + * Do not parse such instruction. */ 254 + if (strstr(endptr, "(%r") == NULL) 255 + ops->target.addr = strtoull(endptr, NULL, 16); 256 + } 251 257 goto find_target; 252 258 } 253 259 ··· 282 276 return ins->ops == &call_ops || ins->ops == &s390_call_ops; 283 277 } 284 278 285 - static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms) 279 + /* 280 + * Prevents from matching commas in the comment section, e.g.: 281 + * ffff200008446e70: b.cs ffff2000084470f4 <generic_exec_single+0x314> // b.hs, b.nlast 282 + */ 283 + static inline const char *validate_comma(const char *c, struct ins_operands *ops) 284 + { 285 + if (ops->raw_comment && c > ops->raw_comment) 286 + return NULL; 287 + 288 + return c; 289 + } 290 + 291 + static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) 286 292 { 287 293 struct map *map = ms->map; 288 294 struct symbol *sym = ms->sym; ··· 303 285 }; 304 286 const char *c = strchr(ops->raw, ','); 305 287 u64 start, end; 288 + 289 + ops->raw_comment = strchr(ops->raw, arch->objdump.comment_char); 290 + c = validate_comma(c, ops); 291 + 306 292 /* 307 293 * Examples of lines to parse for the _cpp_lex_token@@Base 308 294 * function: ··· 326 304 ops->target.addr = strtoull(c, NULL, 16); 327 305 if (!ops->target.addr) { 328 306 c = strchr(c, ','); 307 + c = validate_comma(c, ops); 329 308 if (c++ != NULL) 330 309 ops->target.addr = strtoull(c, NULL, 16); 331 310 } ··· 384 361 return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name); 385 362 386 363 c = strchr(ops->raw, ','); 364 + c = validate_comma(c, ops); 365 + 387 366 if (c != NULL) { 388 367 const char *c2 = strchr(c + 1, ','); 389 368 369 + c2 = validate_comma(c2, ops); 390 370 /* check for 3-op insn */ 391 371 if (c2 != NULL) 392 372 c = c2;
+1
tools/perf/util/annotate.h
··· 22 22 23 23 struct ins_operands { 24 24 char *raw; 25 + char *raw_comment; 25 26 struct { 26 27 char *raw; 27 28 char *name;
+3 -2
tools/perf/util/evsel.c
··· 251 251 { 252 252 struct perf_evsel *evsel = zalloc(perf_evsel__object.size); 253 253 254 - if (evsel != NULL) 255 - perf_evsel__init(evsel, attr, idx); 254 + if (!evsel) 255 + return NULL; 256 + perf_evsel__init(evsel, attr, idx); 256 257 257 258 if (perf_evsel__is_bpf_output(evsel)) { 258 259 evsel->attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
+1 -1
tools/perf/util/trace-event-info.c
··· 377 377 378 378 static int record_saved_cmdline(void) 379 379 { 380 - unsigned int size; 380 + unsigned long long size; 381 381 char *path; 382 382 struct stat st; 383 383 int ret, err = 0;
+3 -4
tools/perf/util/trace-event-parse.c
··· 164 164 void parse_saved_cmdline(struct tep_handle *pevent, 165 165 char *file, unsigned int size __maybe_unused) 166 166 { 167 - char *comm; 167 + char comm[17]; /* Max comm length in the kernel is 16. */ 168 168 char *line; 169 169 char *next = NULL; 170 170 int pid; 171 171 172 172 line = strtok_r(file, "\n", &next); 173 173 while (line) { 174 - sscanf(line, "%d %ms", &pid, &comm); 175 - tep_register_comm(pevent, comm, pid); 176 - free(comm); 174 + if (sscanf(line, "%d %16s", &pid, comm) == 2) 175 + tep_register_comm(pevent, comm, pid); 177 176 line = strtok_r(NULL, "\n", &next); 178 177 } 179 178 }