-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'perf-urgent-for-mingo-4.19-20180903' of git://git.kernel.o…
…rg/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>
- Loading branch information
Showing
15 changed files
with
282 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#include <linux/compiler.h> | ||
#include <sys/types.h> | ||
#include <sys/wait.h> | ||
#include <sys/user.h> | ||
#include <syscall.h> | ||
#include <unistd.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <sys/ptrace.h> | ||
#include <asm/ptrace.h> | ||
#include <errno.h> | ||
#include "debug.h" | ||
#include "tests/tests.h" | ||
#include "arch-tests.h" | ||
|
||
static noinline int bp_1(void) | ||
{ | ||
pr_debug("in %s\n", __func__); | ||
return 0; | ||
} | ||
|
||
static noinline int bp_2(void) | ||
{ | ||
pr_debug("in %s\n", __func__); | ||
return 0; | ||
} | ||
|
||
static int spawn_child(void) | ||
{ | ||
int child = fork(); | ||
|
||
if (child == 0) { | ||
/* | ||
* The child sets itself for as tracee and | ||
* waits in signal for parent to trace it, | ||
* then it calls bp_1 and quits. | ||
*/ | ||
int err = ptrace(PTRACE_TRACEME, 0, NULL, NULL); | ||
|
||
if (err) { | ||
pr_debug("failed to PTRACE_TRACEME\n"); | ||
exit(1); | ||
} | ||
|
||
raise(SIGCONT); | ||
bp_1(); | ||
exit(0); | ||
} | ||
|
||
return child; | ||
} | ||
|
||
/* | ||
* This tests creates HW breakpoint, tries to | ||
* change it and checks it was properly changed. | ||
*/ | ||
static int bp_modify1(void) | ||
{ | ||
pid_t child; | ||
int status; | ||
unsigned long rip = 0, dr7 = 1; | ||
|
||
child = spawn_child(); | ||
|
||
waitpid(child, &status, 0); | ||
if (WIFEXITED(status)) { | ||
pr_debug("tracee exited prematurely 1\n"); | ||
return TEST_FAIL; | ||
} | ||
|
||
/* | ||
* The parent does following steps: | ||
* - creates a new breakpoint (id 0) for bp_2 function | ||
* - changes that breakponit to bp_1 function | ||
* - waits for the breakpoint to hit and checks | ||
* it has proper rip of bp_1 function | ||
* - detaches the child | ||
*/ | ||
if (ptrace(PTRACE_POKEUSER, child, | ||
offsetof(struct user, u_debugreg[0]), bp_2)) { | ||
pr_debug("failed to set breakpoint, 1st time: %s\n", | ||
strerror(errno)); | ||
goto out; | ||
} | ||
|
||
if (ptrace(PTRACE_POKEUSER, child, | ||
offsetof(struct user, u_debugreg[0]), bp_1)) { | ||
pr_debug("failed to set breakpoint, 2nd time: %s\n", | ||
strerror(errno)); | ||
goto out; | ||
} | ||
|
||
if (ptrace(PTRACE_POKEUSER, child, | ||
offsetof(struct user, u_debugreg[7]), dr7)) { | ||
pr_debug("failed to set dr7: %s\n", strerror(errno)); | ||
goto out; | ||
} | ||
|
||
if (ptrace(PTRACE_CONT, child, NULL, NULL)) { | ||
pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno)); | ||
goto out; | ||
} | ||
|
||
waitpid(child, &status, 0); | ||
if (WIFEXITED(status)) { | ||
pr_debug("tracee exited prematurely 2\n"); | ||
return TEST_FAIL; | ||
} | ||
|
||
rip = ptrace(PTRACE_PEEKUSER, child, | ||
offsetof(struct user_regs_struct, rip), NULL); | ||
if (rip == (unsigned long) -1) { | ||
pr_debug("failed to PTRACE_PEEKUSER: %s\n", | ||
strerror(errno)); | ||
goto out; | ||
} | ||
|
||
pr_debug("rip %lx, bp_1 %p\n", rip, bp_1); | ||
|
||
out: | ||
if (ptrace(PTRACE_DETACH, child, NULL, NULL)) { | ||
pr_debug("failed to PTRACE_DETACH: %s", strerror(errno)); | ||
return TEST_FAIL; | ||
} | ||
|
||
return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; | ||
} | ||
|
||
/* | ||
* This tests creates HW breakpoint, tries to | ||
* change it to bogus value and checks the original | ||
* breakpoint is hit. | ||
*/ | ||
static int bp_modify2(void) | ||
{ | ||
pid_t child; | ||
int status; | ||
unsigned long rip = 0, dr7 = 1; | ||
|
||
child = spawn_child(); | ||
|
||
waitpid(child, &status, 0); | ||
if (WIFEXITED(status)) { | ||
pr_debug("tracee exited prematurely 1\n"); | ||
return TEST_FAIL; | ||
} | ||
|
||
/* | ||
* The parent does following steps: | ||
* - creates a new breakpoint (id 0) for bp_1 function | ||
* - tries to change that breakpoint to (-1) address | ||
* - waits for the breakpoint to hit and checks | ||
* it has proper rip of bp_1 function | ||
* - detaches the child | ||
*/ | ||
if (ptrace(PTRACE_POKEUSER, child, | ||
offsetof(struct user, u_debugreg[0]), bp_1)) { | ||
pr_debug("failed to set breakpoint: %s\n", | ||
strerror(errno)); | ||
goto out; | ||
} | ||
|
||
if (ptrace(PTRACE_POKEUSER, child, | ||
offsetof(struct user, u_debugreg[7]), dr7)) { | ||
pr_debug("failed to set dr7: %s\n", strerror(errno)); | ||
goto out; | ||
} | ||
|
||
if (!ptrace(PTRACE_POKEUSER, child, | ||
offsetof(struct user, u_debugreg[0]), (unsigned long) (-1))) { | ||
pr_debug("failed, breakpoint set to bogus address\n"); | ||
goto out; | ||
} | ||
|
||
if (ptrace(PTRACE_CONT, child, NULL, NULL)) { | ||
pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno)); | ||
goto out; | ||
} | ||
|
||
waitpid(child, &status, 0); | ||
if (WIFEXITED(status)) { | ||
pr_debug("tracee exited prematurely 2\n"); | ||
return TEST_FAIL; | ||
} | ||
|
||
rip = ptrace(PTRACE_PEEKUSER, child, | ||
offsetof(struct user_regs_struct, rip), NULL); | ||
if (rip == (unsigned long) -1) { | ||
pr_debug("failed to PTRACE_PEEKUSER: %s\n", | ||
strerror(errno)); | ||
goto out; | ||
} | ||
|
||
pr_debug("rip %lx, bp_1 %p\n", rip, bp_1); | ||
|
||
out: | ||
if (ptrace(PTRACE_DETACH, child, NULL, NULL)) { | ||
pr_debug("failed to PTRACE_DETACH: %s", strerror(errno)); | ||
return TEST_FAIL; | ||
} | ||
|
||
return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; | ||
} | ||
|
||
int test__bp_modify(struct test *test __maybe_unused, | ||
int subtest __maybe_unused) | ||
{ | ||
TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1()); | ||
TEST_ASSERT_VAL("modify test 2 failed\n", !bp_modify2()); | ||
|
||
return 0; | ||
} |
Oops, something went wrong.