Messages in this thread Patch in this message | | | From | Jiri Olsa <> | Subject | [PATCH 03/15] perf: Unified API to record selective sets of arch registers | Date | Wed, 28 Mar 2012 14:35:46 +0200 |
| |
This brings a new API to help the selective dump of registers on event sampling, and its implementation in x86.
- The informations about the desired registers will be passed to a single u64 mask. It's up to the architecture to map the registers into the mask bits.
- The architecture must provide a non-zero and unique id to identify the origin of a register set because interpreting a register dump requires to know from which architecture it comes. The achitecture is considered different between the 32 and 64 bits version. x86-32 has the id 1, x86-64 has the id 2.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Jiri Olsa <jolsa@redhat.com> --- arch/Kconfig | 7 +++ arch/x86/Kconfig | 1 + arch/x86/include/asm/perf_regs.h | 15 +++++ arch/x86/include/asm/perf_regs_32.h | 86 +++++++++++++++++++++++++++++ arch/x86/include/asm/perf_regs_64.h | 101 +++++++++++++++++++++++++++++++++++ 5 files changed, 210 insertions(+), 0 deletions(-) create mode 100644 arch/x86/include/asm/perf_regs.h create mode 100644 arch/x86/include/asm/perf_regs_32.h create mode 100644 arch/x86/include/asm/perf_regs_64.h
diff --git a/arch/Kconfig b/arch/Kconfig index cfddeb0..aa83dda 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -204,6 +204,13 @@ config HAVE_PERF_EVENTS_NMI subsystem. Also has support for calculating CPU cycle events to determine how many clock cycles in a given period. +config HAVE_PERF_REGS_DEFS + bool + help + Support selective register dumps for perf events. This includes + bit-mapping of each registers and a unique architecture version, + also different between 32 and 64 bits. + config HAVE_ARCH_JUMP_LABEL bool diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1b61bd8..556cda9 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -59,6 +59,7 @@ config X86 select HAVE_MIXED_BREAKPOINTS_REGS select PERF_EVENTS select HAVE_PERF_EVENTS_NMI + select HAVE_PERF_REGS_DEFS select ANON_INODES select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386 select HAVE_CMPXCHG_LOCAL if !M386 diff --git a/arch/x86/include/asm/perf_regs.h b/arch/x86/include/asm/perf_regs.h new file mode 100644 index 0000000..df3dec7 --- /dev/null +++ b/arch/x86/include/asm/perf_regs.h @@ -0,0 +1,15 @@ +#ifndef _ASM_X86_PERF_REGS_H +#define _ASM_X86_PERF_REGS_H + +enum { + PERF_X86_32_REG_VERSION = 1UL, + PERF_X86_64_REG_VERSION = 2UL, +}; + +#ifdef CONFIG_X86_32 +#include "perf_regs_32.h" +#else +#include "perf_regs_64.h" +#endif + +#endif /* _ASM_X86_PERF_REGS_H */ diff --git a/arch/x86/include/asm/perf_regs_32.h b/arch/x86/include/asm/perf_regs_32.h new file mode 100644 index 0000000..b38d8b4 --- /dev/null +++ b/arch/x86/include/asm/perf_regs_32.h @@ -0,0 +1,86 @@ +#ifndef _ASM_X86_PERF_REGS_32_H +#define _ASM_X86_PERF_REGS_32_H + +#define PERF_X86_32_REG_VERSION 1ULL + +enum perf_event_x86_32_regs { + PERF_X86_32_REG_EAX, + PERF_X86_32_REG_EBX, + PERF_X86_32_REG_ECX, + PERF_X86_32_REG_EDX, + PERF_X86_32_REG_ESI, + PERF_X86_32_REG_EDI, + PERF_X86_32_REG_EBP, + PERF_X86_32_REG_ESP, + PERF_X86_32_REG_EIP, + PERF_X86_32_REG_FLAGS, + PERF_X86_32_REG_CS, + PERF_X86_32_REG_DS, + PERF_X86_32_REG_ES, + PERF_X86_32_REG_FS, + PERF_X86_32_REG_GS, + + /* Non ABI */ + PERF_X86_32_REG_MAX, + PERF_REG_IP = PERF_X86_32_REG_EIP, + PERF_REG_SP = PERF_X86_32_REG_ESP, +}; + +#ifdef __KERNEL__ + +#define PERF_X86_32_REG_RESERVED (~((1ULL << PERF_X86_32_REG_MAX) - 1ULL)) + +static inline u64 perf_reg_version(void) +{ + return PERF_X86_32_REG_VERSION; +} + +static inline int perf_reg_validate(u64 mask) +{ + if (mask & PERF_X86_32_REG_RESERVED) + return -EINVAL; + + return 0; +} + +static inline u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + switch (idx) { + case PERF_X86_32_REG_EAX: + return regs->ax; + case PERF_X86_32_REG_EBX: + return regs->bx; + case PERF_X86_32_REG_ECX: + return regs->cx; + case PERF_X86_32_REG_EDX: + return regs->dx; + case PERF_X86_32_REG_ESI: + return regs->si; + case PERF_X86_32_REG_EDI: + return regs->di; + case PERF_X86_32_REG_EBP: + return regs->bp; + case PERF_X86_32_REG_ESP: + return regs->sp; + case PERF_X86_32_REG_EIP: + return regs->ip; + case PERF_X86_32_REG_FLAGS: + return regs->flags; + case PERF_X86_32_REG_CS: + return regs->cs; + case PERF_X86_32_REG_DS: + return regs->ds; + case PERF_X86_32_REG_ES: + return regs->es; + case PERF_X86_32_REG_FS: + return regs->fs; + case PERF_X86_32_REG_GS: + return regs->gs; + } + + return 0; +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_X86_PERF_REGS_32_H */ diff --git a/arch/x86/include/asm/perf_regs_64.h b/arch/x86/include/asm/perf_regs_64.h new file mode 100644 index 0000000..88f8eb1 --- /dev/null +++ b/arch/x86/include/asm/perf_regs_64.h @@ -0,0 +1,101 @@ +#ifndef _ASM_X86_PERF_REGS_64_H +#define _ASM_X86_PERF_REGS_64_H + +#define PERF_X86_64_REG_VERSION 1ULL + +enum perf_event_x86_64_regs { + PERF_X86_64_REG_RAX, + PERF_X86_64_REG_RBX, + PERF_X86_64_REG_RCX, + PERF_X86_64_REG_RDX, + PERF_X86_64_REG_RSI, + PERF_X86_64_REG_RDI, + PERF_X86_64_REG_R8, + PERF_X86_64_REG_R9, + PERF_X86_64_REG_R10, + PERF_X86_64_REG_R11, + PERF_X86_64_REG_R12, + PERF_X86_64_REG_R13, + PERF_X86_64_REG_R14, + PERF_X86_64_REG_R15, + PERF_X86_64_REG_RBP, + PERF_X86_64_REG_RSP, + PERF_X86_64_REG_RIP, + PERF_X86_64_REG_FLAGS, + PERF_X86_64_REG_CS, + PERF_X86_64_REG_SS, + + /* Non ABI */ + PERF_X86_64_REG_MAX, + PERF_REG_IP = PERF_X86_64_REG_RIP, + PERF_REG_SP = PERF_X86_64_REG_RSP, +}; + +#ifdef __KERNEL__ + +#define PERF_X86_64_REG_RESERVED (~((1ULL << PERF_X86_64_REG_MAX) - 1ULL)) + +static inline u64 perf_reg_version(void) +{ + return PERF_X86_64_REG_VERSION; +} + +static inline int perf_reg_validate(u64 mask) +{ + if (mask & PERF_X86_64_REG_RESERVED) + return -EINVAL; + + return 0; +} + +static inline u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + switch (idx) { + case PERF_X86_64_REG_RAX: + return regs->ax; + case PERF_X86_64_REG_RBX: + return regs->bx; + case PERF_X86_64_REG_RCX: + return regs->cx; + case PERF_X86_64_REG_RDX: + return regs->dx; + case PERF_X86_64_REG_RSI: + return regs->si; + case PERF_X86_64_REG_RDI: + return regs->di; + case PERF_X86_64_REG_R8: + return regs->r8; + case PERF_X86_64_REG_R9: + return regs->r8; + case PERF_X86_64_REG_R10: + return regs->r8; + case PERF_X86_64_REG_R11: + return regs->r8; + case PERF_X86_64_REG_R12: + return regs->r8; + case PERF_X86_64_REG_R13: + return regs->r8; + case PERF_X86_64_REG_R14: + return regs->r8; + case PERF_X86_64_REG_R15: + return regs->r8; + case PERF_X86_64_REG_RBP: + return regs->bp; + case PERF_X86_64_REG_RSP: + return regs->sp; + case PERF_X86_64_REG_RIP: + return regs->ip; + case PERF_X86_64_REG_FLAGS: + return regs->flags; + case PERF_X86_64_REG_CS: + return regs->cs; + case PERF_X86_64_REG_SS: + return regs->ss; + } + + return 0; +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_X86_PERF_REGS_64_H */ -- 1.7.1
| |