-
Notifications
You must be signed in to change notification settings - Fork 53.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
s390/perf: add support for perf_regs and libdw
With support for perf_regs and libdw, you can record and report call graphs for user space programs. Simply invoke perf with the --call-graph=dwarf command line option. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> [brueckner: added dwfl_thread_state_register_pc() call] Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Reviewed-and-tested-by: Thomas Richter <tmricht@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
- Loading branch information
Showing
5 changed files
with
113 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#ifndef ARCH_PERF_REGS_H | ||
#define ARCH_PERF_REGS_H | ||
|
||
#include <stdlib.h> | ||
#include <linux/types.h> | ||
#include <../../../../arch/s390/include/uapi/asm/perf_regs.h> | ||
|
||
void perf_regs_load(u64 *regs); | ||
|
||
#define PERF_REGS_MASK ((1ULL << PERF_REG_S390_MAX) - 1) | ||
#define PERF_REGS_MAX PERF_REG_S390_MAX | ||
#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 | ||
|
||
#define PERF_REG_IP PERF_REG_S390_PC | ||
#define PERF_REG_SP PERF_REG_S390_R15 | ||
|
||
static inline const char *perf_reg_name(int id) | ||
{ | ||
switch (id) { | ||
case PERF_REG_S390_R0: | ||
return "R0"; | ||
case PERF_REG_S390_R1: | ||
return "R1"; | ||
case PERF_REG_S390_R2: | ||
return "R2"; | ||
case PERF_REG_S390_R3: | ||
return "R3"; | ||
case PERF_REG_S390_R4: | ||
return "R4"; | ||
case PERF_REG_S390_R5: | ||
return "R5"; | ||
case PERF_REG_S390_R6: | ||
return "R6"; | ||
case PERF_REG_S390_R7: | ||
return "R7"; | ||
case PERF_REG_S390_R8: | ||
return "R8"; | ||
case PERF_REG_S390_R9: | ||
return "R9"; | ||
case PERF_REG_S390_R10: | ||
return "R10"; | ||
case PERF_REG_S390_R11: | ||
return "R11"; | ||
case PERF_REG_S390_R12: | ||
return "R12"; | ||
case PERF_REG_S390_R13: | ||
return "R13"; | ||
case PERF_REG_S390_R14: | ||
return "R14"; | ||
case PERF_REG_S390_R15: | ||
return "R15"; | ||
case PERF_REG_S390_MASK: | ||
return "MASK"; | ||
case PERF_REG_S390_PC: | ||
return "PC"; | ||
default: | ||
return NULL; | ||
} | ||
|
||
return NULL; | ||
} | ||
|
||
#endif /* ARCH_PERF_REGS_H */ |
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,40 @@ | ||
#include <elfutils/libdwfl.h> | ||
#include "../../util/unwind-libdw.h" | ||
#include "../../util/perf_regs.h" | ||
#include "../../util/event.h" | ||
|
||
|
||
bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) | ||
{ | ||
struct unwind_info *ui = arg; | ||
struct regs_dump *user_regs = &ui->sample->user_regs; | ||
Dwarf_Word dwarf_regs[PERF_REG_S390_MAX]; | ||
|
||
#define REG(r) ({ \ | ||
Dwarf_Word val = 0; \ | ||
perf_reg_value(&val, user_regs, PERF_REG_S390_##r); \ | ||
val; \ | ||
}) | ||
|
||
dwarf_regs[0] = REG(R0); | ||
dwarf_regs[1] = REG(R1); | ||
dwarf_regs[2] = REG(R2); | ||
dwarf_regs[3] = REG(R3); | ||
dwarf_regs[4] = REG(R4); | ||
dwarf_regs[5] = REG(R5); | ||
dwarf_regs[6] = REG(R6); | ||
dwarf_regs[7] = REG(R7); | ||
dwarf_regs[8] = REG(R8); | ||
dwarf_regs[9] = REG(R9); | ||
dwarf_regs[10] = REG(R10); | ||
dwarf_regs[11] = REG(R11); | ||
dwarf_regs[12] = REG(R12); | ||
dwarf_regs[13] = REG(R13); | ||
dwarf_regs[14] = REG(R14); | ||
dwarf_regs[15] = REG(R15); | ||
dwarf_regs[16] = REG(MASK); | ||
dwarf_regs[17] = REG(PC); | ||
|
||
dwfl_thread_state_register_pc(thread, dwarf_regs[17]); | ||
return dwfl_thread_state_registers(thread, 0, 16, dwarf_regs); | ||
} |