From 49863894db3ed7bd41541b1c17733273966cea71 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 26 Sep 2013 12:36:35 +0100 Subject: ARM: perf: add support for perf registers API This patch implements the functions required for the perf registers API, allowing the perf tool to interface kernel register dumps with libunwind in order to provide userspace backtracing. Cc: Jean Pihet Signed-off-by: Will Deacon --- arch/arm/Kconfig | 2 ++ arch/arm/include/uapi/asm/Kbuild | 1 + arch/arm/include/uapi/asm/perf_regs.h | 23 +++++++++++++++++++++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/perf_regs.c | 30 ++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+) create mode 100644 arch/arm/include/uapi/asm/perf_regs.h create mode 100644 arch/arm/kernel/perf_regs.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1ad6fb6c094d..899d0c6ec2c5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -51,6 +51,8 @@ config ARM select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild index 18d76fd5a2af..70a1c9da30ca 100644 --- a/arch/arm/include/uapi/asm/Kbuild +++ b/arch/arm/include/uapi/asm/Kbuild @@ -7,6 +7,7 @@ header-y += hwcap.h header-y += ioctls.h header-y += kvm_para.h header-y += mman.h +header-y += perf_regs.h header-y += posix_types.h header-y += ptrace.h header-y += setup.h diff --git a/arch/arm/include/uapi/asm/perf_regs.h b/arch/arm/include/uapi/asm/perf_regs.h new file mode 100644 index 000000000000..ce59448458b2 --- /dev/null +++ b/arch/arm/include/uapi/asm/perf_regs.h @@ -0,0 +1,23 @@ +#ifndef _ASM_ARM_PERF_REGS_H +#define _ASM_ARM_PERF_REGS_H + +enum perf_event_arm_regs { + PERF_REG_ARM_R0, + PERF_REG_ARM_R1, + PERF_REG_ARM_R2, + PERF_REG_ARM_R3, + PERF_REG_ARM_R4, + PERF_REG_ARM_R5, + PERF_REG_ARM_R6, + PERF_REG_ARM_R7, + PERF_REG_ARM_R8, + PERF_REG_ARM_R9, + PERF_REG_ARM_R10, + PERF_REG_ARM_FP, + PERF_REG_ARM_IP, + PERF_REG_ARM_SP, + PERF_REG_ARM_LR, + PERF_REG_ARM_PC, + PERF_REG_ARM_MAX, +}; +#endif /* _ASM_ARM_PERF_REGS_H */ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 5140df5f23aa..9b818ca3610b 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o +obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c new file mode 100644 index 000000000000..6e4379c67cbc --- /dev/null +++ b/arch/arm/kernel/perf_regs.c @@ -0,0 +1,30 @@ + +#include +#include +#include +#include +#include +#include + +u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX)) + return 0; + + return regs->uregs[idx]; +} + +#define REG_RESERVED (~((1ULL << PERF_REG_ARM_MAX) - 1)) + +int perf_reg_validate(u64 mask) +{ + if (!mask || mask & REG_RESERVED) + return -EINVAL; + + return 0; +} + +u64 perf_reg_abi(struct task_struct *task) +{ + return PERF_SAMPLE_REGS_ABI_32; +} -- cgit v1.2.3 From 2dfcb802d6bd54a2353678c6434846d94b058f2c Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 9 Oct 2013 13:51:29 +0100 Subject: ARM: perf: fix group validation for mixed software and hardware groups Since software events can always be scheduled, perf allows software and hardware events to be mixed together in the same event group. There are two ways in which this can come about: (1) A SW event is added to a HW group. This validates using the HW PMU of the group leader. (2) A HW event is added to a SW group. This inserts the SW events and the new HW event into a HW context, but the SW event remains the group leader. When validating the latter case, we would ideally compare the PMU of each event in the group with the relevant HW PMU. The problem is, in the face of potentially multiple HW PMUs, we don't have a handle on the relevant structure. Commit 7b9f72c62ed0 ("ARM: perf: clean up event group validation") attempting to resolve this issue, but actually made things *worse* by comparing with the leader PMU. If the leader is a SW event, then we automatically `pass' all the HW events during validation! This patch removes the check against the leader PMU. Whilst this will allow events from multiple HW PMUs to be grouped together, that should probably be dealt with in perf core as the result of a later patch. Acked-by: Mark Rutland Signed-off-by: Will Deacon --- arch/arm/kernel/perf_event.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index e186ee1e63f6..bc3f2efa0d86 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -256,12 +256,11 @@ validate_event(struct pmu_hw_events *hw_events, struct perf_event *event) { struct arm_pmu *armpmu = to_arm_pmu(event->pmu); - struct pmu *leader_pmu = event->group_leader->pmu; if (is_software_event(event)) return 1; - if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) + if (event->state < PERF_EVENT_STATE_OFF) return 1; if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) -- cgit v1.2.3