lkml.org 
[lkml]   [2012]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: [PATCH 02/16] perf: Unified API to record selective sets of arch registers
From
On Tue, Apr 17, 2012 at 1:17 PM, Jiri Olsa <jolsa@redhat.com> wrote:
> 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/x86/include/asm/perf_regs.h    |   16 ++++++
>  arch/x86/include/asm/perf_regs_32.h |   84 +++++++++++++++++++++++++++++
>  arch/x86/include/asm/perf_regs_64.h |  101 +++++++++++++++++++++++++++++++++++
>  include/asm-generic/perf_regs.h     |   23 ++++++++
>  4 files changed, 224 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
>  create mode 100644 include/asm-generic/perf_regs.h
>
> diff --git a/arch/x86/include/asm/perf_regs.h b/arch/x86/include/asm/perf_regs.h
> new file mode 100644
> index 0000000..80b7fbe
> --- /dev/null
> +++ b/arch/x86/include/asm/perf_regs.h
> @@ -0,0 +1,16 @@
> +#ifndef _ASM_X86_PERF_REGS_H
> +#define _ASM_X86_PERF_REGS_H
> +
> +enum {
> +       PERF_REGS_VERSION_NONE   = 0UL,
> +       PERF_REGS_VERSION_X86_32 = 1UL,
> +       PERF_REGS_VERSION_X86_64 = 2UL,
> +};
> +
I don't really like the term VERSION here. It's not a versioning
problem you're trying to solve. It's an ABI problem, unless I am
mistaken. You should rename to PERF_REGS_ABI_X86_32 and
PERF_REGS_ABI_X86_64.

I assume the NONE is here to cover the case where you don't
have a user machine state, i.e., hit a kernel thread. Is that right?


> +#ifdef CONFIG_X86_32
> +#include "perf_regs_32.h"
> +#else
> +#include "perf_regs_64.h"
> +#endif
> +
How are you going to deal with 32-bit binaries sampled on a 64-bit system?

> +#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..3c5aa80
> --- /dev/null
> +++ b/arch/x86/include/asm/perf_regs_32.h
> @@ -0,0 +1,84 @@
> +#ifndef _ASM_X86_PERF_REGS_32_H
> +#define _ASM_X86_PERF_REGS_32_H
> +
> +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_REGS_VERSION_X86_32;
> +}
> +
> +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..d775213
> --- /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_REGS_VERSION_X86_64;
> +}
> +
> +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->r9;
> +       case PERF_X86_64_REG_R10:
> +               return regs->r10;
> +       case PERF_X86_64_REG_R11:
> +               return regs->r11;
> +       case PERF_X86_64_REG_R12:
> +               return regs->r12;
> +       case PERF_X86_64_REG_R13:
> +               return regs->r13;
> +       case PERF_X86_64_REG_R14:
> +               return regs->r14;
> +       case PERF_X86_64_REG_R15:
> +               return regs->r15;
> +       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 */
> diff --git a/include/asm-generic/perf_regs.h b/include/asm-generic/perf_regs.h
> new file mode 100644
> index 0000000..f616096
> --- /dev/null
> +++ b/include/asm-generic/perf_regs.h
> @@ -0,0 +1,23 @@
> +#ifndef __ASM_GENERIC_PERF_REGS_H
> +#define __ASM_GENERIC_PERF_REGS_H
> +
> +enum {
> +       PERF_REGS_VERSION_NONE = 0UL,
> +};
> +
> +static inline int perf_reg_value(struct pt_regs *regs, int idx)
> +{
> +       return 0;
> +}
> +
> +static inline int perf_reg_version(void)
> +{
> +       return PERF_REGS_VERSION_NONE;
> +}
> +
> +static inline int perf_reg_validate(u64 mask)
> +{
> +       return mask ? -ENOSYS : 0;
> +}
> +
> +#endif /* __ASM_GENERIC_PERF_REGS_H */
> --
> 1.7.7.6
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2012-04-23 12:13    [W:0.136 / U:8.824 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site