* [PATCH 0/2] add perf-probe support on ARM @ 2010-06-23 9:36 Will Deacon 2010-06-23 9:36 ` [PATCH 1/2] ARM: Add kprobe-based event tracer Will Deacon ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Will Deacon @ 2010-06-23 9:36 UTC (permalink / raw) To: linux-arm-kernel Perf-probe uses the KProbe events tracer to place and monitor probes on the running Kernel. This patch series adds both Kernel and tool support for this feature on ARM. Patches based on 2.6.35-rc3 [although perf record is currently broken on all architectures for probe tracepoints. These patches also apply cleanly to -tip/master where perf record works properly.] Cc: Jamie Iles <jamie.iles@picochip.com> Cc: Jean Pihet <jpihet@mvista.com> Will Deacon (2): ARM: Add kprobe-based event tracer ARM: perf probe: Add ARM DWARF register number mappings arch/arm/Kconfig | 1 + arch/arm/include/asm/ptrace.h | 36 ++++++++++++ arch/arm/kernel/ptrace.c | 96 +++++++++++++++++++++++++++++++++ tools/perf/arch/arm/Makefile | 4 ++ tools/perf/arch/arm/util/dwarf-regs.c | 64 ++++++++++++++++++++++ 5 files changed, 201 insertions(+), 0 deletions(-) create mode 100644 tools/perf/arch/arm/Makefile create mode 100644 tools/perf/arch/arm/util/dwarf-regs.c ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] ARM: Add kprobe-based event tracer 2010-06-23 9:36 [PATCH 0/2] add perf-probe support on ARM Will Deacon @ 2010-06-23 9:36 ` Will Deacon 2010-06-23 9:36 ` [PATCH 2/2] ARM: perf probe: Add ARM DWARF register number mappings Will Deacon 2010-06-25 8:14 ` [PATCH 0/2] add perf-probe support on ARM Jamie Iles 2010-06-25 10:26 ` Jean Pihet 2 siblings, 1 reply; 7+ messages in thread From: Will Deacon @ 2010-06-23 9:36 UTC (permalink / raw) To: linux-arm-kernel This patch enables the HAVE_REGS_AND_STACK_ACCESS_API option for ARM which is required by the kprobe events tracer. Code based on the PowerPC port. Cc: Jamie Iles <jamie.iles@picochip.com> Cc: Jean Pihet <jpihet@mvista.com> Signed-off-by: Will Deacon <will.deacon@arm.com> --- arch/arm/Kconfig | 1 + arch/arm/include/asm/ptrace.h | 36 +++++++++++++++ arch/arm/kernel/ptrace.c | 96 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 0 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e57cb24..e0e7de6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -24,6 +24,7 @@ config ARM select HAVE_KERNEL_LZMA select HAVE_PERF_EVENTS select PERF_USE_VMALLOC + select HAVE_REGS_AND_STACK_ACCESS_API help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 9dcb11e..c974be8 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -184,6 +184,42 @@ extern unsigned long profile_pc(struct pt_regs *regs); #define predicate(x) ((x) & 0xf0000000) #define PREDICATE_ALWAYS 0xe0000000 +/* + * kprobe-based event tracer support + */ +#include <linux/stddef.h> +#include <linux/types.h> +#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0)) + +extern int regs_query_register_offset(const char *name); +extern const char *regs_query_register_name(unsigned int offset); +extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr); +extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n); + +/** + * regs_get_register() - get register value from its offset + * @regs: pt_regs from which register value is gotten + * @offset: offset number of the register. + * + * regs_get_register returns the value of a register whose offset from @regs. + * The @offset is the offset of the register in struct pt_regs. + * If @offset is bigger than MAX_REG_OFFSET, this returns 0. + */ +static inline unsigned long regs_get_register(struct pt_regs *regs, + unsigned int offset) +{ + if (unlikely(offset > MAX_REG_OFFSET)) + return 0; + return *(unsigned long *)((unsigned long)regs + offset); +} + +/* Valid only for Kernel mode traps. */ +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + return regs->ARM_sp; +} + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 3f562a7..f99d489 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -52,6 +52,102 @@ #define BREAKINST_THUMB 0xde01 #endif +struct pt_regs_offset { + const char *name; + int offset; +}; + +#define REG_OFFSET_NAME(r) \ + {.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)} +#define REG_OFFSET_END {.name = NULL, .offset = 0} + +static const struct pt_regs_offset regoffset_table[] = { + REG_OFFSET_NAME(r0), + REG_OFFSET_NAME(r1), + REG_OFFSET_NAME(r2), + REG_OFFSET_NAME(r3), + REG_OFFSET_NAME(r4), + REG_OFFSET_NAME(r5), + REG_OFFSET_NAME(r6), + REG_OFFSET_NAME(r7), + REG_OFFSET_NAME(r8), + REG_OFFSET_NAME(r9), + REG_OFFSET_NAME(r10), + REG_OFFSET_NAME(fp), + REG_OFFSET_NAME(ip), + REG_OFFSET_NAME(sp), + REG_OFFSET_NAME(lr), + REG_OFFSET_NAME(pc), + REG_OFFSET_NAME(cpsr), + REG_OFFSET_NAME(ORIG_r0), + REG_OFFSET_END, +}; + +/** + * regs_query_register_offset() - query register offset from its name + * @name: the name of a register + * + * regs_query_register_offset() returns the offset of a register in struct + * pt_regs from its name. If the name is invalid, this returns -EINVAL; + */ +int regs_query_register_offset(const char *name) +{ + const struct pt_regs_offset *roff; + for (roff = regoffset_table; roff->name != NULL; roff++) + if (!strcmp(roff->name, name)) + return roff->offset; + return -EINVAL; +} + +/** + * regs_query_register_name() - query register name from its offset + * @offset: the offset of a register in struct pt_regs. + * + * regs_query_register_name() returns the name of a register from its + * offset in struct pt_regs. If the @offset is invalid, this returns NULL; + */ +const char *regs_query_register_name(unsigned int offset) +{ + const struct pt_regs_offset *roff; + for (roff = regoffset_table; roff->name != NULL; roff++) + if (roff->offset == offset) + return roff->name; + return NULL; +} + +/** + * regs_within_kernel_stack() - check the address in the stack + * @regs: pt_regs which contains kernel stack pointer. + * @addr: address which is checked. + * + * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). + * If @addr is within the kernel stack, it returns true. If not, returns false. + */ +bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) +{ + return ((addr & ~(THREAD_SIZE - 1)) == + (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs: pt_regs which contains kernel stack pointer. + * @n: stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specified by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) +{ + unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); + addr += n; + if (regs_within_kernel_stack(regs, (unsigned long)addr)) + return *addr; + else + return 0; +} + /* * this routine will get a word off of the processes privileged stack. * the offset is how far from the base addr as stored in the THREAD. -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] ARM: perf probe: Add ARM DWARF register number mappings 2010-06-23 9:36 ` [PATCH 1/2] ARM: Add kprobe-based event tracer Will Deacon @ 2010-06-23 9:36 ` Will Deacon 0 siblings, 0 replies; 7+ messages in thread From: Will Deacon @ 2010-06-23 9:36 UTC (permalink / raw) To: linux-arm-kernel This patch adds mappings from DWARF register numbers to the register names used by the ARM `Regs and Stack Access API'. Cc: Jamie Iles <jamie.iles@picochip.com> Cc: Jean Pihet <jpihet@mvista.com> Signed-off-by: Will Deacon <will.deacon@arm.com> --- tools/perf/arch/arm/Makefile | 4 ++ tools/perf/arch/arm/util/dwarf-regs.c | 64 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 0 deletions(-) create mode 100644 tools/perf/arch/arm/Makefile create mode 100644 tools/perf/arch/arm/util/dwarf-regs.c diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile new file mode 100644 index 0000000..15130b5 --- /dev/null +++ b/tools/perf/arch/arm/Makefile @@ -0,0 +1,4 @@ +ifndef NO_DWARF +PERF_HAVE_DWARF_REGS := 1 +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o +endif diff --git a/tools/perf/arch/arm/util/dwarf-regs.c b/tools/perf/arch/arm/util/dwarf-regs.c new file mode 100644 index 0000000..fff6450 --- /dev/null +++ b/tools/perf/arch/arm/util/dwarf-regs.c @@ -0,0 +1,64 @@ +/* + * Mapping of DWARF debug register numbers into register names. + * + * Copyright (C) 2010 Will Deacon, ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <libio.h> +#include <dwarf-regs.h> + +struct pt_regs_dwarfnum { + const char *name; + unsigned int dwarfnum; +}; + +#define STR(s) #s +#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num} +#define GPR_DWARFNUM_NAME(num) \ + {.name = STR(%r##num), .dwarfnum = num} +#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0} + +/* + * Reference: + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040a/IHI0040A_aadwarf.pdf + */ +static const struct pt_regs_dwarfnum regdwarfnum_table[] = { + GPR_DWARFNUM_NAME(0), + GPR_DWARFNUM_NAME(1), + GPR_DWARFNUM_NAME(2), + GPR_DWARFNUM_NAME(3), + GPR_DWARFNUM_NAME(4), + GPR_DWARFNUM_NAME(5), + GPR_DWARFNUM_NAME(6), + GPR_DWARFNUM_NAME(7), + GPR_DWARFNUM_NAME(8), + GPR_DWARFNUM_NAME(9), + GPR_DWARFNUM_NAME(10), + REG_DWARFNUM_NAME("%fp", 11), + REG_DWARFNUM_NAME("%ip", 12), + REG_DWARFNUM_NAME("%sp", 13), + REG_DWARFNUM_NAME("%lr", 14), + REG_DWARFNUM_NAME("%pc", 15), + REG_DWARFNUM_END, +}; + +/** + * get_arch_regstr() - lookup register name from it's DWARF register number + * @n: the DWARF register number + * + * get_arch_regstr() returns the name of the register in struct + * regdwarfnum_table from it's DWARF register number. If the register is not + * found in the table, this returns NULL; + */ +const char *get_arch_regstr(unsigned int n) +{ + const struct pt_regs_dwarfnum *roff; + for (roff = regdwarfnum_table; roff->name != NULL; roff++) + if (roff->dwarfnum == n) + return roff->name; + return NULL; +} -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 0/2] add perf-probe support on ARM 2010-06-23 9:36 [PATCH 0/2] add perf-probe support on ARM Will Deacon 2010-06-23 9:36 ` [PATCH 1/2] ARM: Add kprobe-based event tracer Will Deacon @ 2010-06-25 8:14 ` Jamie Iles 2010-06-25 9:51 ` Will Deacon 2010-06-25 10:26 ` Jean Pihet 2 siblings, 1 reply; 7+ messages in thread From: Jamie Iles @ 2010-06-25 8:14 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jun 23, 2010 at 10:36:01AM +0100, Will Deacon wrote: > Perf-probe uses the KProbe events tracer to place and monitor probes > on the running Kernel. > > This patch series adds both Kernel and tool support for this feature > on ARM. > > Patches based on 2.6.35-rc3 [although perf record is currently broken > on all architectures for probe tracepoints. These patches also apply > cleanly to -tip/master where perf record works properly.] > > Cc: Jamie Iles <jamie.iles@picochip.com> > Cc: Jean Pihet <jpihet@mvista.com> > > Will Deacon (2): > ARM: Add kprobe-based event tracer > ARM: perf probe: Add ARM DWARF register number mappings > > arch/arm/Kconfig | 1 + > arch/arm/include/asm/ptrace.h | 36 ++++++++++++ > arch/arm/kernel/ptrace.c | 96 +++++++++++++++++++++++++++++++++ > tools/perf/arch/arm/Makefile | 4 ++ > tools/perf/arch/arm/util/dwarf-regs.c | 64 ++++++++++++++++++++++ > 5 files changed, 201 insertions(+), 0 deletions(-) > create mode 100644 tools/perf/arch/arm/Makefile > create mode 100644 tools/perf/arch/arm/util/dwarf-regs.c Hi Will, I've had a quick play on an ARMv6 board and these patches look good and appear to work! Tested-by: Jamie Iles <jamie.iles@picochip.com> Jamie ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 0/2] add perf-probe support on ARM 2010-06-25 8:14 ` [PATCH 0/2] add perf-probe support on ARM Jamie Iles @ 2010-06-25 9:51 ` Will Deacon 0 siblings, 0 replies; 7+ messages in thread From: Will Deacon @ 2010-06-25 9:51 UTC (permalink / raw) To: linux-arm-kernel Hi Jamie, > I've had a quick play on an ARMv6 board and these patches look good and appear > to work! > > Tested-by: Jamie Iles <jamie.iles@picochip.com> Cracking, thanks for this. I'll stick them in the patch system. Will ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 0/2] add perf-probe support on ARM 2010-06-23 9:36 [PATCH 0/2] add perf-probe support on ARM Will Deacon 2010-06-23 9:36 ` [PATCH 1/2] ARM: Add kprobe-based event tracer Will Deacon 2010-06-25 8:14 ` [PATCH 0/2] add perf-probe support on ARM Jamie Iles @ 2010-06-25 10:26 ` Jean Pihet 2010-06-25 10:35 ` Will Deacon 2 siblings, 1 reply; 7+ messages in thread From: Jean Pihet @ 2010-06-25 10:26 UTC (permalink / raw) To: linux-arm-kernel Hi Will, Are more tests needed for ARMv7 (OMAP3430/3530/3517)? I hope to find some time to test it if required. Regards, Jean On Wed, Jun 23, 2010 at 11:36, Will Deacon <will.deacon@arm.com> wrote: > Perf-probe uses the KProbe events tracer to place and monitor probes > on the running Kernel. > > This patch series adds both Kernel and tool support for this feature > on ARM. > > Patches based on 2.6.35-rc3 [although perf record is currently broken > on all architectures for probe tracepoints. These patches also apply > cleanly to -tip/master where perf record works properly.] > > Cc: Jamie Iles <jamie.iles@picochip.com> > Cc: Jean Pihet <jpihet@mvista.com> > > Will Deacon (2): > ARM: Add kprobe-based event tracer > ARM: perf probe: Add ARM DWARF register number mappings > > arch/arm/Kconfig | 1 + > arch/arm/include/asm/ptrace.h | 36 ++++++++++++ > arch/arm/kernel/ptrace.c | 96 > +++++++++++++++++++++++++++++++++ > tools/perf/arch/arm/Makefile | 4 ++ > tools/perf/arch/arm/util/dwarf-regs.c | 64 ++++++++++++++++++++++ > 5 files changed, 201 insertions(+), 0 deletions(-) > create mode 100644 tools/perf/arch/arm/Makefile > create mode 100644 tools/perf/arch/arm/util/dwarf-regs.c > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100625/61827ff4/attachment.html> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 0/2] add perf-probe support on ARM 2010-06-25 10:26 ` Jean Pihet @ 2010-06-25 10:35 ` Will Deacon 0 siblings, 0 replies; 7+ messages in thread From: Will Deacon @ 2010-06-25 10:35 UTC (permalink / raw) To: linux-arm-kernel > Hi Will, Hi Jean, > Are more tests needed for ARMv7 (OMAP3430/3530/3517)? I hope to find some time to test it if required. The patches don't do anything special for the different architectures and I've tried it on a quad-core A9 board so I don't think you're required to test it as well. Having said that, it's a pretty neat tool so you might want to have a play :) Thanks, Will ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-06-25 10:35 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-06-23 9:36 [PATCH 0/2] add perf-probe support on ARM Will Deacon 2010-06-23 9:36 ` [PATCH 1/2] ARM: Add kprobe-based event tracer Will Deacon 2010-06-23 9:36 ` [PATCH 2/2] ARM: perf probe: Add ARM DWARF register number mappings Will Deacon 2010-06-25 8:14 ` [PATCH 0/2] add perf-probe support on ARM Jamie Iles 2010-06-25 9:51 ` Will Deacon 2010-06-25 10:26 ` Jean Pihet 2010-06-25 10:35 ` Will Deacon
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).