linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/3] perf: AARCH64 arch support
@ 2014-02-03 18:18 Jean Pihet
  2014-02-03 18:18 ` [PATCH 1/3] ARM64: perf: add support for perf registers API Jean Pihet
                   ` (3 more replies)
  0 siblings, 4 replies; 23+ messages in thread
From: Jean Pihet @ 2014-02-03 18:18 UTC (permalink / raw)
  To: linux-kernel, linaro-kernel, linux-arm-kernel, Will Deacon
  Cc: Arnaldo, Ingo Molnar, Jiri Olsa, patches, Jean Pihet

Add AARCH64 specific support. This includes the following:
- AARCH64 perf registers definition and hooks,
- compat mode registers use, i.e. profiling a 32-bit binary on
   a 64-bit system,
- unwinding using the dwarf information from the .debug_frame
   section of the ELF binary,
- unwinding using the frame pointer information; in 64-bit and
   compat modes.

Notes:
- the tools/perf change is submitted separately on LKML,
- support for unwinding using the dwarf information in compat
mode requires some changes to the libunwind code. Those changes
have been submitted on the libunwind ML and are in discussion.

Tested on ARMv7, ARMv8 and x86_64 platforms. The compat mode has been
tested on ARMv8 using statically built 32-bit binaries.


Jean Pihet (3):
  ARM64: perf: add support for perf registers API
  ARM64: perf: add support for frame pointer unwinding in compat mode
  ARM64: perf: support dwarf unwinding in compat mode

 arch/arm64/Kconfig                      |  2 +
 arch/arm64/include/asm/compat.h         |  2 +-
 arch/arm64/include/asm/ptrace.h         |  3 +-
 arch/arm64/include/uapi/asm/Kbuild      |  1 +
 arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++
 arch/arm64/kernel/Makefile              |  1 +
 arch/arm64/kernel/perf_event.c          | 75 +++++++++++++++++++++++++++++----
 arch/arm64/kernel/perf_regs.c           | 44 +++++++++++++++++++
 8 files changed, 158 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm64/include/uapi/asm/perf_regs.h
 create mode 100644 arch/arm64/kernel/perf_regs.c

-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/3] ARM64: perf: add support for perf registers API
  2014-02-03 18:18 [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
@ 2014-02-03 18:18 ` Jean Pihet
  2014-03-13  7:27   ` [tip:perf/core] ARM64, perf: Add " tip-bot for Jean Pihet
  2014-02-03 18:18 ` [PATCH 2/3] ARM64: perf: add support for frame pointer unwinding in compat mode Jean Pihet
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 23+ messages in thread
From: Jean Pihet @ 2014-02-03 18:18 UTC (permalink / raw)
  To: linux-kernel, linaro-kernel, linux-arm-kernel, Will Deacon
  Cc: Arnaldo, Ingo Molnar, Jiri Olsa, patches, Jean Pihet

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.
Compat mode is also supported.

Only the general purpose user space registers are exported, i.e.:
 PERF_REG_ARM_X0,
 ...
 PERF_REG_ARM_X28,
 PERF_REG_ARM_FP,
 PERF_REG_ARM_LR,
 PERF_REG_ARM_SP,
 PERF_REG_ARM_PC
and not the PERF_REG_ARM_V* registers.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig                      |  2 ++
 arch/arm64/include/asm/ptrace.h         |  1 +
 arch/arm64/include/uapi/asm/Kbuild      |  1 +
 arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++++
 arch/arm64/kernel/Makefile              |  1 +
 arch/arm64/kernel/perf_regs.c           | 44 +++++++++++++++++++++++++++++++++
 6 files changed, 89 insertions(+)
 create mode 100644 arch/arm64/include/uapi/asm/perf_regs.h
 create mode 100644 arch/arm64/kernel/perf_regs.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index dd4327f..e9899bb 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -37,6 +37,8 @@ config ARM64
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS
 	select HAVE_MEMBLOCK
 	select HAVE_PERF_EVENTS
+	select HAVE_PERF_REGS
+	select HAVE_PERF_USER_STACK_DUMP
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0e7fa49..fbb0020 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -68,6 +68,7 @@
 
 /* Architecturally defined mapping between AArch32 and AArch64 registers */
 #define compat_usr(x)	regs[(x)]
+#define compat_fp	regs[11]
 #define compat_sp	regs[13]
 #define compat_lr	regs[14]
 #define compat_sp_hyp	regs[15]
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
index e4b78bd..942376d 100644
--- a/arch/arm64/include/uapi/asm/Kbuild
+++ b/arch/arm64/include/uapi/asm/Kbuild
@@ -9,6 +9,7 @@ header-y += byteorder.h
 header-y += fcntl.h
 header-y += hwcap.h
 header-y += kvm_para.h
+header-y += perf_regs.h
 header-y += param.h
 header-y += ptrace.h
 header-y += setup.h
diff --git a/arch/arm64/include/uapi/asm/perf_regs.h b/arch/arm64/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000..172b831
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/perf_regs.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_ARM64_PERF_REGS_H
+#define _ASM_ARM64_PERF_REGS_H
+
+enum perf_event_arm_regs {
+	PERF_REG_ARM64_X0,
+	PERF_REG_ARM64_X1,
+	PERF_REG_ARM64_X2,
+	PERF_REG_ARM64_X3,
+	PERF_REG_ARM64_X4,
+	PERF_REG_ARM64_X5,
+	PERF_REG_ARM64_X6,
+	PERF_REG_ARM64_X7,
+	PERF_REG_ARM64_X8,
+	PERF_REG_ARM64_X9,
+	PERF_REG_ARM64_X10,
+	PERF_REG_ARM64_X11,
+	PERF_REG_ARM64_X12,
+	PERF_REG_ARM64_X13,
+	PERF_REG_ARM64_X14,
+	PERF_REG_ARM64_X15,
+	PERF_REG_ARM64_X16,
+	PERF_REG_ARM64_X17,
+	PERF_REG_ARM64_X18,
+	PERF_REG_ARM64_X19,
+	PERF_REG_ARM64_X20,
+	PERF_REG_ARM64_X21,
+	PERF_REG_ARM64_X22,
+	PERF_REG_ARM64_X23,
+	PERF_REG_ARM64_X24,
+	PERF_REG_ARM64_X25,
+	PERF_REG_ARM64_X26,
+	PERF_REG_ARM64_X27,
+	PERF_REG_ARM64_X28,
+	PERF_REG_ARM64_X29,
+	PERF_REG_ARM64_LR,
+	PERF_REG_ARM64_SP,
+	PERF_REG_ARM64_PC,
+	PERF_REG_ARM64_MAX,
+};
+#endif /* _ASM_ARM64_PERF_REGS_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2d4554b..9a5d592 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -15,6 +15,7 @@ arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o
+arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c
new file mode 100644
index 0000000..f2d6f0a
--- /dev/null
+++ b/arch/arm64/kernel/perf_regs.c
@@ -0,0 +1,44 @@
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+	if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
+		return 0;
+
+	/*
+	 * Compat (i.e. 32 bit) mode:
+	 * - PC has been set in the pt_regs struct in kernel_entry,
+	 * - Handle SP and LR here.
+	 */
+	if (compat_user_mode(regs)) {
+		if ((u32)idx == PERF_REG_ARM64_SP)
+			return regs->compat_sp;
+		if ((u32)idx == PERF_REG_ARM64_LR)
+			return regs->compat_lr;
+	}
+
+	return regs->regs[idx];
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_ARM64_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)
+{
+	if (is_compat_thread(task_thread_info(task)))
+		return PERF_SAMPLE_REGS_ABI_32;
+	else
+		return PERF_SAMPLE_REGS_ABI_64;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/3] ARM64: perf: add support for frame pointer unwinding in compat mode
  2014-02-03 18:18 [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
  2014-02-03 18:18 ` [PATCH 1/3] ARM64: perf: add support for perf registers API Jean Pihet
@ 2014-02-03 18:18 ` Jean Pihet
  2014-03-13  7:27   ` [tip:perf/core] ARM64, perf: Add " tip-bot for Jean Pihet
  2014-02-03 18:18 ` [PATCH 3/3] ARM64: perf: support dwarf " Jean Pihet
  2014-02-12  8:47 ` [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
  3 siblings, 1 reply; 23+ messages in thread
From: Jean Pihet @ 2014-02-03 18:18 UTC (permalink / raw)
  To: linux-kernel, linaro-kernel, linux-arm-kernel, Will Deacon
  Cc: Arnaldo, Ingo Molnar, Jiri Olsa, patches, Jean Pihet

When profiling a 32-bit application, user space callchain unwinding
using the frame pointer is performed in compat mode. The code is taken
over from the AARCH32 code and adapted to work on AARCH64.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/perf_event.c | 75 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 5b1cd79..e868c72 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1348,8 +1348,8 @@ early_initcall(init_hw_perf_events);
  * Callchain handling code.
  */
 struct frame_tail {
-	struct frame_tail   __user *fp;
-	unsigned long	    lr;
+	struct frame_tail	__user *fp;
+	unsigned long		lr;
 } __attribute__((packed));
 
 /*
@@ -1386,22 +1386,80 @@ user_backtrace(struct frame_tail __user *tail,
 	return buftail.fp;
 }
 
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct compat_frame_tail *)(xxx->fp)-1
+ *
+ * This code has been adapted from the ARM OProfile support.
+ */
+struct compat_frame_tail {
+	compat_uptr_t	fp; /* a (struct compat_frame_tail *) in compat mode */
+	u32		sp;
+	u32		lr;
+} __attribute__((packed));
+
+static struct compat_frame_tail __user *
+compat_user_backtrace(struct compat_frame_tail __user *tail,
+		      struct perf_callchain_entry *entry)
+{
+	struct compat_frame_tail buftail;
+	unsigned long err;
+
+	/* Also check accessibility of one struct frame_tail beyond */
+	if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+		return NULL;
+
+	pagefault_disable();
+	err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
+	pagefault_enable();
+
+	if (err)
+		return NULL;
+
+	perf_callchain_store(entry, buftail.lr);
+
+	/*
+	 * Frame pointers should strictly progress back up the stack
+	 * (towards higher addresses).
+	 */
+	if (tail + 1 >= (struct compat_frame_tail __user *)
+			compat_ptr(buftail.fp))
+		return NULL;
+
+	return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1;
+}
+
 void perf_callchain_user(struct perf_callchain_entry *entry,
 			 struct pt_regs *regs)
 {
-	struct frame_tail __user *tail;
-
 	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
 
 	perf_callchain_store(entry, regs->pc);
-	tail = (struct frame_tail __user *)regs->regs[29];
 
-	while (entry->nr < PERF_MAX_STACK_DEPTH &&
-	       tail && !((unsigned long)tail & 0xf))
-		tail = user_backtrace(tail, entry);
+	if (!compat_user_mode(regs)) {
+		/* AARCH64 mode */
+		struct frame_tail __user *tail;
+
+		tail = (struct frame_tail __user *)regs->regs[29];
+
+		while (entry->nr < PERF_MAX_STACK_DEPTH &&
+		       tail && !((unsigned long)tail & 0xf))
+			tail = user_backtrace(tail, entry);
+	} else {
+		/* AARCH32 compat mode */
+		struct compat_frame_tail __user *tail;
+
+		tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
+
+		while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
+			tail && !((unsigned long)tail & 0x3))
+			tail = compat_user_backtrace(tail, entry);
+	}
 }
 
 /*
@@ -1429,6 +1487,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry,
 	frame.fp = regs->regs[29];
 	frame.sp = regs->sp;
 	frame.pc = regs->pc;
+
 	walk_stackframe(&frame, callchain_trace, entry);
 }
 
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/3] ARM64: perf: support dwarf unwinding in compat mode
  2014-02-03 18:18 [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
  2014-02-03 18:18 ` [PATCH 1/3] ARM64: perf: add support for perf registers API Jean Pihet
  2014-02-03 18:18 ` [PATCH 2/3] ARM64: perf: add support for frame pointer unwinding in compat mode Jean Pihet
@ 2014-02-03 18:18 ` Jean Pihet
  2014-03-13  7:28   ` [tip:perf/core] ARM64, perf: Support " tip-bot for Jean Pihet
  2014-02-12  8:47 ` [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
  3 siblings, 1 reply; 23+ messages in thread
From: Jean Pihet @ 2014-02-03 18:18 UTC (permalink / raw)
  To: linux-kernel, linaro-kernel, linux-arm-kernel, Will Deacon
  Cc: Arnaldo, Ingo Molnar, Jiri Olsa, patches, Jean Pihet

Add support for unwinding using the dwarf information in compat
mode. Using the correct user stack pointer allows perf to record
the frames correctly in the native and compat modes.

Note that although the dwarf frame unwinding works ok using
libunwind in native mode (on ARMv7 & ARMv8), some changes are
required to the libunwind code for the compat mode. Those changes
are posted separately on the libunwind mailing list.

Tested on ARMv8 platform with v8 and compat v7 binaries, the latter
are statically built.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/compat.h | 2 +-
 arch/arm64/include/asm/ptrace.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index fda2704..e71f81f 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -228,7 +228,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
 	return (u32)(unsigned long)uptr;
 }
 
-#define compat_user_stack_pointer() (current_pt_regs()->compat_sp)
+#define compat_user_stack_pointer() (user_stack_pointer(current_pt_regs()))
 
 static inline void __user *arch_compat_alloc_user_space(long len)
 {
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index fbb0020..86d5b54 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -133,7 +133,7 @@ struct pt_regs {
 	(!((regs)->pstate & PSR_F_BIT))
 
 #define user_stack_pointer(regs) \
-	((regs)->sp)
+	(!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp)
 
 /*
  * Are the current registers suitable for user mode? (used to maintain
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v6 0/3] perf: AARCH64 arch support
  2014-02-03 18:18 [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
                   ` (2 preceding siblings ...)
  2014-02-03 18:18 ` [PATCH 3/3] ARM64: perf: support dwarf " Jean Pihet
@ 2014-02-12  8:47 ` Jean Pihet
  2014-02-12 10:09   ` Will Deacon
  3 siblings, 1 reply; 23+ messages in thread
From: Jean Pihet @ 2014-02-12  8:47 UTC (permalink / raw)
  To: linux-kernel, linaro-kernel, linux-arm-kernel, Will Deacon
  Cc: Arnaldo, Ingo Molnar, Jiri Olsa, Patch Tracking, Jean Pihet

Hi Will,

Ping on the series. Is this OK for inclusion?

Regards,
Jean

On 3 February 2014 19:18, Jean Pihet <jean.pihet@linaro.org> wrote:
> Add AARCH64 specific support. This includes the following:
> - AARCH64 perf registers definition and hooks,
> - compat mode registers use, i.e. profiling a 32-bit binary on
>    a 64-bit system,
> - unwinding using the dwarf information from the .debug_frame
>    section of the ELF binary,
> - unwinding using the frame pointer information; in 64-bit and
>    compat modes.
>
> Notes:
> - the tools/perf change is submitted separately on LKML,
> - support for unwinding using the dwarf information in compat
> mode requires some changes to the libunwind code. Those changes
> have been submitted on the libunwind ML and are in discussion.
>
> Tested on ARMv7, ARMv8 and x86_64 platforms. The compat mode has been
> tested on ARMv8 using statically built 32-bit binaries.
>
>
> Jean Pihet (3):
>   ARM64: perf: add support for perf registers API
>   ARM64: perf: add support for frame pointer unwinding in compat mode
>   ARM64: perf: support dwarf unwinding in compat mode
>
>  arch/arm64/Kconfig                      |  2 +
>  arch/arm64/include/asm/compat.h         |  2 +-
>  arch/arm64/include/asm/ptrace.h         |  3 +-
>  arch/arm64/include/uapi/asm/Kbuild      |  1 +
>  arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++
>  arch/arm64/kernel/Makefile              |  1 +
>  arch/arm64/kernel/perf_event.c          | 75 +++++++++++++++++++++++++++++----
>  arch/arm64/kernel/perf_regs.c           | 44 +++++++++++++++++++
>  8 files changed, 158 insertions(+), 10 deletions(-)
>  create mode 100644 arch/arm64/include/uapi/asm/perf_regs.h
>  create mode 100644 arch/arm64/kernel/perf_regs.c
>
> --
> 1.7.11.7
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v6 0/3] perf: AARCH64 arch support
  2014-02-12  8:47 ` [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
@ 2014-02-12 10:09   ` Will Deacon
  2014-03-12 10:19     ` Jean Pihet
  0 siblings, 1 reply; 23+ messages in thread
From: Will Deacon @ 2014-02-12 10:09 UTC (permalink / raw)
  To: Jean Pihet
  Cc: linux-kernel, linaro-kernel, linux-arm-kernel, Arnaldo,
	Ingo Molnar, Jiri Olsa, Patch Tracking

On Wed, Feb 12, 2014 at 08:47:17AM +0000, Jean Pihet wrote:
> Ping on the series. Is this OK for inclusion?

I already acked it all, but you'll need to wait until the next merge window
since this isn't a fix.

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v6 0/3] perf: AARCH64 arch support
  2014-02-12 10:09   ` Will Deacon
@ 2014-03-12 10:19     ` Jean Pihet
  2014-03-12 17:31       ` Catalin Marinas
  0 siblings, 1 reply; 23+ messages in thread
From: Jean Pihet @ 2014-03-12 10:19 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-kernel, linaro-kernel, linux-arm-kernel, Arnaldo,
	Ingo Molnar, Jiri Olsa, Patch Tracking

Hi!

Gentle ping on this series? Which tree is it supposed to land in?

I have a new series about libdw integration and unwinding built-in
test for AARCH64, which is based on this one. How to handle it?

Regards,
Jean

On 12 February 2014 11:09, Will Deacon <will.deacon@arm.com> wrote:
> On Wed, Feb 12, 2014 at 08:47:17AM +0000, Jean Pihet wrote:
>> Ping on the series. Is this OK for inclusion?
>
> I already acked it all, but you'll need to wait until the next merge window
> since this isn't a fix.
>
> Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v6 0/3] perf: AARCH64 arch support
  2014-03-12 10:19     ` Jean Pihet
@ 2014-03-12 17:31       ` Catalin Marinas
  2014-03-13 12:02         ` Jean Pihet
  0 siblings, 1 reply; 23+ messages in thread
From: Catalin Marinas @ 2014-03-12 17:31 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Will Deacon, linaro-kernel, Patch Tracking, linux-kernel,
	Arnaldo, Jiri Olsa, Ingo Molnar, linux-arm-kernel

On Wed, Mar 12, 2014 at 11:19:48AM +0100, Jean Pihet wrote:
> Gentle ping on this series? Which tree is it supposed to land in?

Since it's only arm64 stuff and Will already acked the series, I'm going
to merge it via the arm64 tree. Consider it applied (for the upcoming
merging window).

-- 
Catalin

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [tip:perf/core] ARM64, perf: Add support for perf registers API
  2014-02-03 18:18 ` [PATCH 1/3] ARM64: perf: add support for perf registers API Jean Pihet
@ 2014-03-13  7:27   ` tip-bot for Jean Pihet
  2014-03-13 10:19     ` Catalin Marinas
  0 siblings, 1 reply; 23+ messages in thread
From: tip-bot for Jean Pihet @ 2014-03-13  7:27 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, will.deacon, acme, jean.pihet, jolsa, tglx

Commit-ID:  1acfb01a43db9d8cde2d4c1d51746bae0b46b06b
Gitweb:     http://git.kernel.org/tip/1acfb01a43db9d8cde2d4c1d51746bae0b46b06b
Author:     Jean Pihet <jean.pihet@linaro.org>
AuthorDate: Mon, 3 Feb 2014 19:18:27 +0100
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 12 Mar 2014 13:45:28 +0100

ARM64, 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. Compat mode is also supported.

Only the general purpose user space registers are exported,
i.e.:  PERF_REG_ARM_X0,
 ...
 PERF_REG_ARM_X28,
 PERF_REG_ARM_FP,
 PERF_REG_ARM_LR,
 PERF_REG_ARM_SP,
 PERF_REG_ARM_PC
and not the PERF_REG_ARM_V* registers.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: Arnaldo <acme@ghostprotocols.net>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: patches@linaro.org
Cc: linaro-kernel@lists.linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/1391451509-31265-2-git-send-email-jean.pihet@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/arm64/Kconfig                      |  2 ++
 arch/arm64/include/asm/ptrace.h         |  1 +
 arch/arm64/include/uapi/asm/Kbuild      |  1 +
 arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++++
 arch/arm64/kernel/Makefile              |  1 +
 arch/arm64/kernel/perf_regs.c           | 44 +++++++++++++++++++++++++++++++++
 6 files changed, 89 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 27bbcfc..c8bac62 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -38,6 +38,8 @@ config ARM64
 	select HAVE_MEMBLOCK
 	select HAVE_PATA_PLATFORM
 	select HAVE_PERF_EVENTS
+	select HAVE_PERF_REGS
+	select HAVE_PERF_USER_STACK_DUMP
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0e7fa49..fbb0020 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -68,6 +68,7 @@
 
 /* Architecturally defined mapping between AArch32 and AArch64 registers */
 #define compat_usr(x)	regs[(x)]
+#define compat_fp	regs[11]
 #define compat_sp	regs[13]
 #define compat_lr	regs[14]
 #define compat_sp_hyp	regs[15]
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
index e4b78bd..942376d 100644
--- a/arch/arm64/include/uapi/asm/Kbuild
+++ b/arch/arm64/include/uapi/asm/Kbuild
@@ -9,6 +9,7 @@ header-y += byteorder.h
 header-y += fcntl.h
 header-y += hwcap.h
 header-y += kvm_para.h
+header-y += perf_regs.h
 header-y += param.h
 header-y += ptrace.h
 header-y += setup.h
diff --git a/arch/arm64/include/uapi/asm/perf_regs.h b/arch/arm64/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000..172b831
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/perf_regs.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_ARM64_PERF_REGS_H
+#define _ASM_ARM64_PERF_REGS_H
+
+enum perf_event_arm_regs {
+	PERF_REG_ARM64_X0,
+	PERF_REG_ARM64_X1,
+	PERF_REG_ARM64_X2,
+	PERF_REG_ARM64_X3,
+	PERF_REG_ARM64_X4,
+	PERF_REG_ARM64_X5,
+	PERF_REG_ARM64_X6,
+	PERF_REG_ARM64_X7,
+	PERF_REG_ARM64_X8,
+	PERF_REG_ARM64_X9,
+	PERF_REG_ARM64_X10,
+	PERF_REG_ARM64_X11,
+	PERF_REG_ARM64_X12,
+	PERF_REG_ARM64_X13,
+	PERF_REG_ARM64_X14,
+	PERF_REG_ARM64_X15,
+	PERF_REG_ARM64_X16,
+	PERF_REG_ARM64_X17,
+	PERF_REG_ARM64_X18,
+	PERF_REG_ARM64_X19,
+	PERF_REG_ARM64_X20,
+	PERF_REG_ARM64_X21,
+	PERF_REG_ARM64_X22,
+	PERF_REG_ARM64_X23,
+	PERF_REG_ARM64_X24,
+	PERF_REG_ARM64_X25,
+	PERF_REG_ARM64_X26,
+	PERF_REG_ARM64_X27,
+	PERF_REG_ARM64_X28,
+	PERF_REG_ARM64_X29,
+	PERF_REG_ARM64_LR,
+	PERF_REG_ARM64_SP,
+	PERF_REG_ARM64_PC,
+	PERF_REG_ARM64_MAX,
+};
+#endif /* _ASM_ARM64_PERF_REGS_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2d4554b..9a5d592 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -15,6 +15,7 @@ arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o
+arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c
new file mode 100644
index 0000000..f2d6f0a
--- /dev/null
+++ b/arch/arm64/kernel/perf_regs.c
@@ -0,0 +1,44 @@
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+	if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
+		return 0;
+
+	/*
+	 * Compat (i.e. 32 bit) mode:
+	 * - PC has been set in the pt_regs struct in kernel_entry,
+	 * - Handle SP and LR here.
+	 */
+	if (compat_user_mode(regs)) {
+		if ((u32)idx == PERF_REG_ARM64_SP)
+			return regs->compat_sp;
+		if ((u32)idx == PERF_REG_ARM64_LR)
+			return regs->compat_lr;
+	}
+
+	return regs->regs[idx];
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_ARM64_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)
+{
+	if (is_compat_thread(task_thread_info(task)))
+		return PERF_SAMPLE_REGS_ABI_32;
+	else
+		return PERF_SAMPLE_REGS_ABI_64;
+}

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [tip:perf/core] ARM64, perf: Add support for frame pointer unwinding in compat mode
  2014-02-03 18:18 ` [PATCH 2/3] ARM64: perf: add support for frame pointer unwinding in compat mode Jean Pihet
@ 2014-03-13  7:27   ` tip-bot for Jean Pihet
  0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Jean Pihet @ 2014-03-13  7:27 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, will.deacon, acme, jean.pihet, jolsa, tglx

Commit-ID:  a0cb501f9de391077eb18e4675e2be95c3dcf84c
Gitweb:     http://git.kernel.org/tip/a0cb501f9de391077eb18e4675e2be95c3dcf84c
Author:     Jean Pihet <jean.pihet@linaro.org>
AuthorDate: Mon, 3 Feb 2014 19:18:28 +0100
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 12 Mar 2014 13:45:29 +0100

ARM64, perf: Add support for frame pointer unwinding in compat mode

When profiling a 32-bit application, user space callchain
unwinding using the frame pointer is performed in compat mode.
The code is taken over from the AARCH32 code and adapted to work
on AARCH64.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: Arnaldo <acme@ghostprotocols.net>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: patches@linaro.org
Cc: linaro-kernel@lists.linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/1391451509-31265-3-git-send-email-jean.pihet@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/arm64/kernel/perf_event.c | 75 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 5b1cd79..e868c72 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1348,8 +1348,8 @@ early_initcall(init_hw_perf_events);
  * Callchain handling code.
  */
 struct frame_tail {
-	struct frame_tail   __user *fp;
-	unsigned long	    lr;
+	struct frame_tail	__user *fp;
+	unsigned long		lr;
 } __attribute__((packed));
 
 /*
@@ -1386,22 +1386,80 @@ user_backtrace(struct frame_tail __user *tail,
 	return buftail.fp;
 }
 
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct compat_frame_tail *)(xxx->fp)-1
+ *
+ * This code has been adapted from the ARM OProfile support.
+ */
+struct compat_frame_tail {
+	compat_uptr_t	fp; /* a (struct compat_frame_tail *) in compat mode */
+	u32		sp;
+	u32		lr;
+} __attribute__((packed));
+
+static struct compat_frame_tail __user *
+compat_user_backtrace(struct compat_frame_tail __user *tail,
+		      struct perf_callchain_entry *entry)
+{
+	struct compat_frame_tail buftail;
+	unsigned long err;
+
+	/* Also check accessibility of one struct frame_tail beyond */
+	if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+		return NULL;
+
+	pagefault_disable();
+	err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
+	pagefault_enable();
+
+	if (err)
+		return NULL;
+
+	perf_callchain_store(entry, buftail.lr);
+
+	/*
+	 * Frame pointers should strictly progress back up the stack
+	 * (towards higher addresses).
+	 */
+	if (tail + 1 >= (struct compat_frame_tail __user *)
+			compat_ptr(buftail.fp))
+		return NULL;
+
+	return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1;
+}
+
 void perf_callchain_user(struct perf_callchain_entry *entry,
 			 struct pt_regs *regs)
 {
-	struct frame_tail __user *tail;
-
 	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
 
 	perf_callchain_store(entry, regs->pc);
-	tail = (struct frame_tail __user *)regs->regs[29];
 
-	while (entry->nr < PERF_MAX_STACK_DEPTH &&
-	       tail && !((unsigned long)tail & 0xf))
-		tail = user_backtrace(tail, entry);
+	if (!compat_user_mode(regs)) {
+		/* AARCH64 mode */
+		struct frame_tail __user *tail;
+
+		tail = (struct frame_tail __user *)regs->regs[29];
+
+		while (entry->nr < PERF_MAX_STACK_DEPTH &&
+		       tail && !((unsigned long)tail & 0xf))
+			tail = user_backtrace(tail, entry);
+	} else {
+		/* AARCH32 compat mode */
+		struct compat_frame_tail __user *tail;
+
+		tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
+
+		while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
+			tail && !((unsigned long)tail & 0x3))
+			tail = compat_user_backtrace(tail, entry);
+	}
 }
 
 /*
@@ -1429,6 +1487,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry,
 	frame.fp = regs->regs[29];
 	frame.sp = regs->sp;
 	frame.pc = regs->pc;
+
 	walk_stackframe(&frame, callchain_trace, entry);
 }
 

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [tip:perf/core] ARM64, perf: Support dwarf unwinding in compat mode
  2014-02-03 18:18 ` [PATCH 3/3] ARM64: perf: support dwarf " Jean Pihet
@ 2014-03-13  7:28   ` tip-bot for Jean Pihet
  0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Jean Pihet @ 2014-03-13  7:28 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, will.deacon, acme, jean.pihet, jolsa, tglx

Commit-ID:  5aa158b708b07bab47147aa164e3948e8a4c548f
Gitweb:     http://git.kernel.org/tip/5aa158b708b07bab47147aa164e3948e8a4c548f
Author:     Jean Pihet <jean.pihet@linaro.org>
AuthorDate: Mon, 3 Feb 2014 19:18:29 +0100
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 12 Mar 2014 13:45:30 +0100

ARM64, perf: Support dwarf unwinding in compat mode

Add support for unwinding using the dwarf information in compat
mode. Using the correct user stack pointer allows perf to record
the frames correctly in the native and compat modes.

Note that although the dwarf frame unwinding works ok using
libunwind in native mode (on ARMv7 & ARMv8), some changes are
required to the libunwind code for the compat mode. Those
changes are posted separately on the libunwind mailing list.

Tested on ARMv8 platform with v8 and compat v7 binaries, the
latter are statically built.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: Arnaldo <acme@ghostprotocols.net>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: patches@linaro.org
Cc: linaro-kernel@lists.linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/1391451509-31265-4-git-send-email-jean.pihet@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/arm64/include/asm/compat.h | 2 +-
 arch/arm64/include/asm/ptrace.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index fda2704..e71f81f 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -228,7 +228,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
 	return (u32)(unsigned long)uptr;
 }
 
-#define compat_user_stack_pointer() (current_pt_regs()->compat_sp)
+#define compat_user_stack_pointer() (user_stack_pointer(current_pt_regs()))
 
 static inline void __user *arch_compat_alloc_user_space(long len)
 {
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index fbb0020..86d5b54 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -133,7 +133,7 @@ struct pt_regs {
 	(!((regs)->pstate & PSR_F_BIT))
 
 #define user_stack_pointer(regs) \
-	((regs)->sp)
+	(!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp)
 
 /*
  * Are the current registers suitable for user mode? (used to maintain

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [tip:perf/core] ARM64, perf: Add support for perf registers API
  2014-03-13  7:27   ` [tip:perf/core] ARM64, perf: Add " tip-bot for Jean Pihet
@ 2014-03-13 10:19     ` Catalin Marinas
  2014-03-13 11:01       ` Ingo Molnar
  0 siblings, 1 reply; 23+ messages in thread
From: Catalin Marinas @ 2014-03-13 10:19 UTC (permalink / raw)
  To: mingo, hpa, linux-kernel, will.deacon, acme, jean.pihet, jolsa, tglx
  Cc: linux-tip-commits

Hi Ingo,

On Thu, Mar 13, 2014 at 12:27:45AM -0700, tip-bot for Jean Pihet wrote:
> Commit-ID:  1acfb01a43db9d8cde2d4c1d51746bae0b46b06b
> Gitweb:     http://git.kernel.org/tip/1acfb01a43db9d8cde2d4c1d51746bae0b46b06b
> Author:     Jean Pihet <jean.pihet@linaro.org>
> AuthorDate: Mon, 3 Feb 2014 19:18:27 +0100
> Committer:  Ingo Molnar <mingo@kernel.org>
> CommitDate: Wed, 12 Mar 2014 13:45:28 +0100
> 
> ARM64, 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. Compat mode is also supported.
> 
> Only the general purpose user space registers are exported,
> i.e.:  PERF_REG_ARM_X0,
>  ...
>  PERF_REG_ARM_X28,
>  PERF_REG_ARM_FP,
>  PERF_REG_ARM_LR,
>  PERF_REG_ARM_SP,
>  PERF_REG_ARM_PC
> and not the PERF_REG_ARM_V* registers.
> 
> Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
> Acked-by: Will Deacon <will.deacon@arm.com>
> Cc: Arnaldo <acme@ghostprotocols.net>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: patches@linaro.org
> Cc: linaro-kernel@lists.linaro.org
> Cc: linux-arm-kernel@lists.infradead.org
> Link: http://lkml.kernel.org/r/1391451509-31265-2-git-send-email-jean.pihet@linaro.org
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> ---
>  arch/arm64/Kconfig                      |  2 ++
>  arch/arm64/include/asm/ptrace.h         |  1 +
>  arch/arm64/include/uapi/asm/Kbuild      |  1 +
>  arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++++
>  arch/arm64/kernel/Makefile              |  1 +
>  arch/arm64/kernel/perf_regs.c           | 44 +++++++++++++++++++++++++++++++++
>  6 files changed, 89 insertions(+)

As I replied to Jean yesterday, I merged the arch/arm64 patches already
in the arm64 tree. Is it late to drop them from tip (and avoid potential
conflicts)?

But please take the perf tools patch (tools/perf/arch/arm64/...).

Thanks.

-- 
Catalin

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [tip:perf/core] ARM64, perf: Add support for perf registers API
  2014-03-13 10:19     ` Catalin Marinas
@ 2014-03-13 11:01       ` Ingo Molnar
  2014-03-13 11:35         ` Catalin Marinas
  0 siblings, 1 reply; 23+ messages in thread
From: Ingo Molnar @ 2014-03-13 11:01 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: hpa, linux-kernel, will.deacon, acme, jean.pihet, jolsa, tglx,
	linux-tip-commits


* Catalin Marinas <catalin.marinas@arm.com> wrote:

> Hi Ingo,
> 
> On Thu, Mar 13, 2014 at 12:27:45AM -0700, tip-bot for Jean Pihet wrote:
> > Commit-ID:  1acfb01a43db9d8cde2d4c1d51746bae0b46b06b
> > Gitweb:     http://git.kernel.org/tip/1acfb01a43db9d8cde2d4c1d51746bae0b46b06b
> > Author:     Jean Pihet <jean.pihet@linaro.org>
> > AuthorDate: Mon, 3 Feb 2014 19:18:27 +0100
> > Committer:  Ingo Molnar <mingo@kernel.org>
> > CommitDate: Wed, 12 Mar 2014 13:45:28 +0100
> > 
> > ARM64, 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. Compat mode is also supported.
> > 
> > Only the general purpose user space registers are exported,
> > i.e.:  PERF_REG_ARM_X0,
> >  ...
> >  PERF_REG_ARM_X28,
> >  PERF_REG_ARM_FP,
> >  PERF_REG_ARM_LR,
> >  PERF_REG_ARM_SP,
> >  PERF_REG_ARM_PC
> > and not the PERF_REG_ARM_V* registers.
> > 
> > Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
> > Acked-by: Will Deacon <will.deacon@arm.com>
> > Cc: Arnaldo <acme@ghostprotocols.net>
> > Cc: Jiri Olsa <jolsa@redhat.com>
> > Cc: patches@linaro.org
> > Cc: linaro-kernel@lists.linaro.org
> > Cc: linux-arm-kernel@lists.infradead.org
> > Link: http://lkml.kernel.org/r/1391451509-31265-2-git-send-email-jean.pihet@linaro.org
> > Signed-off-by: Ingo Molnar <mingo@kernel.org>
> > ---
> >  arch/arm64/Kconfig                      |  2 ++
> >  arch/arm64/include/asm/ptrace.h         |  1 +
> >  arch/arm64/include/uapi/asm/Kbuild      |  1 +
> >  arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++++
> >  arch/arm64/kernel/Makefile              |  1 +
> >  arch/arm64/kernel/perf_regs.c           | 44 +++++++++++++++++++++++++++++++++
> >  6 files changed, 89 insertions(+)
> 
> As I replied to Jean yesterday, I merged the arch/arm64 patches already
> in the arm64 tree. Is it late to drop them from tip (and avoid potential
> conflicts)?
> 
> But please take the perf tools patch (tools/perf/arch/arm64/...).

Well, I merged them so that the tooling bits can be tested on top of 
that and merged as well.

Anyway, I dropped them, they were still the tail of tip:perf/core.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [tip:perf/core] ARM64, perf: Add support for perf registers API
  2014-03-13 11:01       ` Ingo Molnar
@ 2014-03-13 11:35         ` Catalin Marinas
  0 siblings, 0 replies; 23+ messages in thread
From: Catalin Marinas @ 2014-03-13 11:35 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: hpa, linux-kernel, Will Deacon, acme, jean.pihet, jolsa, tglx,
	linux-tip-commits

On Thu, Mar 13, 2014 at 11:01:21AM +0000, Ingo Molnar wrote:
> * Catalin Marinas <catalin.marinas@arm.com> wrote:
> > On Thu, Mar 13, 2014 at 12:27:45AM -0700, tip-bot for Jean Pihet wrote:
> > > Commit-ID:  1acfb01a43db9d8cde2d4c1d51746bae0b46b06b
> > > Gitweb:     http://git.kernel.org/tip/1acfb01a43db9d8cde2d4c1d51746bae0b46b06b
> > > Author:     Jean Pihet <jean.pihet@linaro.org>
> > > AuthorDate: Mon, 3 Feb 2014 19:18:27 +0100
> > > Committer:  Ingo Molnar <mingo@kernel.org>
> > > CommitDate: Wed, 12 Mar 2014 13:45:28 +0100
> > > 
> > > ARM64, 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. Compat mode is also supported.
> > > 
> > > Only the general purpose user space registers are exported,
> > > i.e.:  PERF_REG_ARM_X0,
> > >  ...
> > >  PERF_REG_ARM_X28,
> > >  PERF_REG_ARM_FP,
> > >  PERF_REG_ARM_LR,
> > >  PERF_REG_ARM_SP,
> > >  PERF_REG_ARM_PC
> > > and not the PERF_REG_ARM_V* registers.
> > > 
> > > Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
> > > Acked-by: Will Deacon <will.deacon@arm.com>
> > > Cc: Arnaldo <acme@ghostprotocols.net>
> > > Cc: Jiri Olsa <jolsa@redhat.com>
> > > Cc: patches@linaro.org
> > > Cc: linaro-kernel@lists.linaro.org
> > > Cc: linux-arm-kernel@lists.infradead.org
> > > Link: http://lkml.kernel.org/r/1391451509-31265-2-git-send-email-jean.pihet@linaro.org
> > > Signed-off-by: Ingo Molnar <mingo@kernel.org>
> > > ---
> > >  arch/arm64/Kconfig                      |  2 ++
> > >  arch/arm64/include/asm/ptrace.h         |  1 +
> > >  arch/arm64/include/uapi/asm/Kbuild      |  1 +
> > >  arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++++
> > >  arch/arm64/kernel/Makefile              |  1 +
> > >  arch/arm64/kernel/perf_regs.c           | 44 +++++++++++++++++++++++++++++++++
> > >  6 files changed, 89 insertions(+)
> > 
> > As I replied to Jean yesterday, I merged the arch/arm64 patches already
> > in the arm64 tree. Is it late to drop them from tip (and avoid potential
> > conflicts)?
> > 
> > But please take the perf tools patch (tools/perf/arch/arm64/...).
> 
> Well, I merged them so that the tooling bits can be tested on top of 
> that and merged as well.

That's why I asked if I should take the tooling bits but Will objected ;).

> Anyway, I dropped them, they were still the tail of tip:perf/core.

Thanks. I assume you still take the tooling patch?

-- 
Catalin

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v6 0/3] perf: AARCH64 arch support
  2014-03-12 17:31       ` Catalin Marinas
@ 2014-03-13 12:02         ` Jean Pihet
  0 siblings, 0 replies; 23+ messages in thread
From: Jean Pihet @ 2014-03-13 12:02 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Will Deacon, linaro-kernel, Patch Tracking, linux-kernel,
	Arnaldo, Jiri Olsa, Ingo Molnar, linux-arm-kernel

Hi Catalin,

On 12 March 2014 18:31, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On Wed, Mar 12, 2014 at 11:19:48AM +0100, Jean Pihet wrote:
>> Gentle ping on this series? Which tree is it supposed to land in?
>
> Since it's only arm64 stuff and Will already acked the series, I'm going
> to merge it via the arm64 tree. Consider it applied (for the upcoming
> merging window).

Great, thanks!

Jean

>
> --
> Catalin

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/3] ARM64: perf: add support for perf registers API
  2014-01-15 11:07       ` Will Deacon
@ 2014-01-16 14:49         ` Jean Pihet
  0 siblings, 0 replies; 23+ messages in thread
From: Jean Pihet @ 2014-01-16 14:49 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-kernel, linaro-kernel, Jiri Olsa, Ingo Molnar, Arnaldo,
	patches, Jean Pihet

Will,

On 15 January 2014 12:07, Will Deacon <will.deacon@arm.com> wrote:
> On Wed, Jan 15, 2014 at 10:30:48AM +0000, Jean Pihet wrote:
>> Hi Will,
>
> Hi Jean,
>
>> On 6 January 2014 19:30, Will Deacon <will.deacon@arm.com> wrote:
>> > On Mon, Dec 30, 2013 at 04:25:30PM +0000, Jean Pihet wrote:
>> >> From: Jean Pihet <jean.pihet@newoldbits.com>
>> >>
>> >> 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.
>> >> Compat mode is also supported.
>> >
>> > [...]
>> >
>> >> +u64 perf_reg_value(struct pt_regs *regs, int idx)
>> >> +{
>> >> +     if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
>> >> +             return 0;
>> >
>> > While this is probably fine, I'd feel more comfortable if you had separate
>> > limit checks for native and compat...
>> In fact in the native and compat modes the same set of registers are
>> accessed, based on the native regs that are registered to the perf
>> event core, cf. the definition of PERF_REGS_MASK in
>> tools/perf/arch/arm64/include/perf_regs.h.
>>
>> The regs set could be registered differently based on the binary to
>> trace, but unfortunately the perf core code does not allow that.
>>
>> I would leave the code as is, what do you think?
>
> Well, what business would a compat task have accessing registers beyond the
> compat subset? Since we don't expose the PC, we can simply lower the limit
> as the compat registers form a prefix of the native registers, no?
Yes it is a good thing to clamp the range of registers, based on the
compat mode.
Unfortunately the perf core code does not handle the compat mode,
instead it always accesses all _native_ registers.

Here is the proposal (after our discussion on IRC):
- use the current patches on ARM64 so that we have a working solution
that one can test/stress/use on real workloads,
- re-factor the perf core code later to make able to handle multiple
ABIs and corresponding registers sets.

Are you ok with that?

Regards,
Jean

>
> Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/3] ARM64: perf: add support for perf registers API
  2014-01-15 10:30     ` Jean Pihet
@ 2014-01-15 11:07       ` Will Deacon
  2014-01-16 14:49         ` Jean Pihet
  0 siblings, 1 reply; 23+ messages in thread
From: Will Deacon @ 2014-01-15 11:07 UTC (permalink / raw)
  To: Jean Pihet
  Cc: linux-kernel, linaro-kernel, Jiri Olsa, Ingo Molnar, Arnaldo,
	patches, Jean Pihet

On Wed, Jan 15, 2014 at 10:30:48AM +0000, Jean Pihet wrote:
> Hi Will,

Hi Jean,

> On 6 January 2014 19:30, Will Deacon <will.deacon@arm.com> wrote:
> > On Mon, Dec 30, 2013 at 04:25:30PM +0000, Jean Pihet wrote:
> >> From: Jean Pihet <jean.pihet@newoldbits.com>
> >>
> >> 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.
> >> Compat mode is also supported.
> >
> > [...]
> >
> >> +u64 perf_reg_value(struct pt_regs *regs, int idx)
> >> +{
> >> +     if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
> >> +             return 0;
> >
> > While this is probably fine, I'd feel more comfortable if you had separate
> > limit checks for native and compat...
> In fact in the native and compat modes the same set of registers are
> accessed, based on the native regs that are registered to the perf
> event core, cf. the definition of PERF_REGS_MASK in
> tools/perf/arch/arm64/include/perf_regs.h.
> 
> The regs set could be registered differently based on the binary to
> trace, but unfortunately the perf core code does not allow that.
> 
> I would leave the code as is, what do you think?

Well, what business would a compat task have accessing registers beyond the
compat subset? Since we don't expose the PC, we can simply lower the limit
as the compat registers form a prefix of the native registers, no?

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/3] ARM64: perf: add support for perf registers API
  2014-01-06 18:30   ` Will Deacon
  2014-01-07  8:49     ` Jean Pihet
@ 2014-01-15 10:30     ` Jean Pihet
  2014-01-15 11:07       ` Will Deacon
  1 sibling, 1 reply; 23+ messages in thread
From: Jean Pihet @ 2014-01-15 10:30 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-kernel, linaro-kernel, Jiri Olsa, Ingo Molnar, Arnaldo,
	patches, Jean Pihet

Hi Will,

On 6 January 2014 19:30, Will Deacon <will.deacon@arm.com> wrote:
> Hi Jean,
>
> Thanks for the updated patches. One minor comment on this one.
>
> On Mon, Dec 30, 2013 at 04:25:30PM +0000, Jean Pihet wrote:
>> From: Jean Pihet <jean.pihet@newoldbits.com>
>>
>> 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.
>> Compat mode is also supported.
>
> [...]
>
>> +u64 perf_reg_value(struct pt_regs *regs, int idx)
>> +{
>> +     if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
>> +             return 0;
>
> While this is probably fine, I'd feel more comfortable if you had separate
> limit checks for native and compat...
In fact in the native and compat modes the same set of registers are
accessed, based on the native regs that are registered to the perf
event core, cf. the definition of PERF_REGS_MASK in
tools/perf/arch/arm64/include/perf_regs.h.

The regs set could be registered differently based on the binary to
trace, but unfortunately the perf core code does not allow that.

I would leave the code as is, what do you think?

Cheers,
Jean

>
>> +     /*
>> +      * Compat (i.e. 32 bit) mode:
>> +      * - PC has been set in the pt_regs struct in kernel_entry,
>> +      * - Handle SP and LR here.
>> +      */
>> +     if (compat_user_mode(regs)) {
>
> i.e. have a WARN_ON_ONCE here for the compat structure size.
>
>> +             if ((u32)idx == PERF_REG_ARM64_SP)
>> +                     return regs->compat_sp;
>> +             if ((u32)idx == PERF_REG_ARM64_LR)
>> +                     return regs->compat_lr;
>> +     }
>
> then stick an else here with the original check.
>
> Make sense?
>
> Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/3] ARM64: perf: add support for perf registers API
  2014-01-06 18:30   ` Will Deacon
@ 2014-01-07  8:49     ` Jean Pihet
  2014-01-15 10:30     ` Jean Pihet
  1 sibling, 0 replies; 23+ messages in thread
From: Jean Pihet @ 2014-01-07  8:49 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-kernel, linaro-kernel, Jiri Olsa, Ingo Molnar, Arnaldo,
	patches, Jean Pihet

Hi Will,

On 6 January 2014 19:30, Will Deacon <will.deacon@arm.com> wrote:
> Hi Jean,
>
> Thanks for the updated patches. One minor comment on this one.
Thanks for reviewing!

> On Mon, Dec 30, 2013 at 04:25:30PM +0000, Jean Pihet wrote:
>> From: Jean Pihet <jean.pihet@newoldbits.com>
>>
>> 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.
>> Compat mode is also supported.
>
> [...]
>
>> +u64 perf_reg_value(struct pt_regs *regs, int idx)
>> +{
>> +     if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
>> +             return 0;
>
> While this is probably fine, I'd feel more comfortable if you had separate
> limit checks for native and compat...
>
>> +     /*
>> +      * Compat (i.e. 32 bit) mode:
>> +      * - PC has been set in the pt_regs struct in kernel_entry,
>> +      * - Handle SP and LR here.
>> +      */
>> +     if (compat_user_mode(regs)) {
>
> i.e. have a WARN_ON_ONCE here for the compat structure size.
>
>> +             if ((u32)idx == PERF_REG_ARM64_SP)
>> +                     return regs->compat_sp;
>> +             if ((u32)idx == PERF_REG_ARM64_LR)
>> +                     return regs->compat_lr;
>> +     }
>
> then stick an else here with the original check.
>
> Make sense?
Yes

I will resend an updated version asap.

>
> Will

Jean

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/3] ARM64: perf: add support for perf registers API
  2013-12-30 16:25 ` [PATCH 1/3] ARM64: perf: add support for perf registers API Jean Pihet
@ 2014-01-06 18:30   ` Will Deacon
  2014-01-07  8:49     ` Jean Pihet
  2014-01-15 10:30     ` Jean Pihet
  0 siblings, 2 replies; 23+ messages in thread
From: Will Deacon @ 2014-01-06 18:30 UTC (permalink / raw)
  To: Jean Pihet
  Cc: linux-kernel, linaro-kernel, Jiri Olsa, Ingo Molnar, Arnaldo,
	patches, Jean Pihet

Hi Jean,

Thanks for the updated patches. One minor comment on this one.

On Mon, Dec 30, 2013 at 04:25:30PM +0000, Jean Pihet wrote:
> From: Jean Pihet <jean.pihet@newoldbits.com>
> 
> 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.
> Compat mode is also supported.

[...]

> +u64 perf_reg_value(struct pt_regs *regs, int idx)
> +{
> +	if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
> +		return 0;

While this is probably fine, I'd feel more comfortable if you had separate
limit checks for native and compat...

> +	/*
> +	 * Compat (i.e. 32 bit) mode:
> +	 * - PC has been set in the pt_regs struct in kernel_entry,
> +	 * - Handle SP and LR here.
> +	 */
> +	if (compat_user_mode(regs)) {

i.e. have a WARN_ON_ONCE here for the compat structure size.

> +		if ((u32)idx == PERF_REG_ARM64_SP)
> +			return regs->compat_sp;
> +		if ((u32)idx == PERF_REG_ARM64_LR)
> +			return regs->compat_lr;
> +	}

then stick an else here with the original check.

Make sense?

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/3] ARM64: perf: add support for perf registers API
  2013-12-30 16:25 [PATCH v4 0/3] perf: add " Jean Pihet
@ 2013-12-30 16:25 ` Jean Pihet
  2014-01-06 18:30   ` Will Deacon
  0 siblings, 1 reply; 23+ messages in thread
From: Jean Pihet @ 2013-12-30 16:25 UTC (permalink / raw)
  To: linux-kernel, linaro-kernel, Jiri Olsa, Ingo Molnar, Arnaldo,
	Will Deacon
  Cc: patches, Jean Pihet, Jean Pihet

From: Jean Pihet <jean.pihet@newoldbits.com>

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.
Compat mode is also supported.

Only the general purpose user space registers are exported, i.e.:
 PERF_REG_ARM_X0,
 ...
 PERF_REG_ARM_X28,
 PERF_REG_ARM_FP,
 PERF_REG_ARM_LR,
 PERF_REG_ARM_SP,
 PERF_REG_ARM_PC
and not the PERF_REG_ARM_V* registers.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig                      |  2 ++
 arch/arm64/include/asm/ptrace.h         |  1 +
 arch/arm64/include/uapi/asm/Kbuild      |  1 +
 arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++++
 arch/arm64/kernel/Makefile              |  1 +
 arch/arm64/kernel/perf_regs.c           | 44 +++++++++++++++++++++++++++++++++
 6 files changed, 89 insertions(+)
 create mode 100644 arch/arm64/include/uapi/asm/perf_regs.h
 create mode 100644 arch/arm64/kernel/perf_regs.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 88c8b6c1..f8609dc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -28,6 +28,8 @@ config ARM64
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS
 	select HAVE_MEMBLOCK
 	select HAVE_PERF_EVENTS
+	select HAVE_PERF_REGS
+	select HAVE_PERF_USER_STACK_DUMP
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0e7fa49..fbb0020 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -68,6 +68,7 @@
 
 /* Architecturally defined mapping between AArch32 and AArch64 registers */
 #define compat_usr(x)	regs[(x)]
+#define compat_fp	regs[11]
 #define compat_sp	regs[13]
 #define compat_lr	regs[14]
 #define compat_sp_hyp	regs[15]
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
index e4b78bd..942376d 100644
--- a/arch/arm64/include/uapi/asm/Kbuild
+++ b/arch/arm64/include/uapi/asm/Kbuild
@@ -9,6 +9,7 @@ header-y += byteorder.h
 header-y += fcntl.h
 header-y += hwcap.h
 header-y += kvm_para.h
+header-y += perf_regs.h
 header-y += param.h
 header-y += ptrace.h
 header-y += setup.h
diff --git a/arch/arm64/include/uapi/asm/perf_regs.h b/arch/arm64/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000..172b831
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/perf_regs.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_ARM64_PERF_REGS_H
+#define _ASM_ARM64_PERF_REGS_H
+
+enum perf_event_arm_regs {
+	PERF_REG_ARM64_X0,
+	PERF_REG_ARM64_X1,
+	PERF_REG_ARM64_X2,
+	PERF_REG_ARM64_X3,
+	PERF_REG_ARM64_X4,
+	PERF_REG_ARM64_X5,
+	PERF_REG_ARM64_X6,
+	PERF_REG_ARM64_X7,
+	PERF_REG_ARM64_X8,
+	PERF_REG_ARM64_X9,
+	PERF_REG_ARM64_X10,
+	PERF_REG_ARM64_X11,
+	PERF_REG_ARM64_X12,
+	PERF_REG_ARM64_X13,
+	PERF_REG_ARM64_X14,
+	PERF_REG_ARM64_X15,
+	PERF_REG_ARM64_X16,
+	PERF_REG_ARM64_X17,
+	PERF_REG_ARM64_X18,
+	PERF_REG_ARM64_X19,
+	PERF_REG_ARM64_X20,
+	PERF_REG_ARM64_X21,
+	PERF_REG_ARM64_X22,
+	PERF_REG_ARM64_X23,
+	PERF_REG_ARM64_X24,
+	PERF_REG_ARM64_X25,
+	PERF_REG_ARM64_X26,
+	PERF_REG_ARM64_X27,
+	PERF_REG_ARM64_X28,
+	PERF_REG_ARM64_X29,
+	PERF_REG_ARM64_LR,
+	PERF_REG_ARM64_SP,
+	PERF_REG_ARM64_PC,
+	PERF_REG_ARM64_MAX,
+};
+#endif /* _ASM_ARM64_PERF_REGS_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 5ba2fd4..dffdd93 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -15,6 +15,7 @@ arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o
+arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c
new file mode 100644
index 0000000..f2d6f0a
--- /dev/null
+++ b/arch/arm64/kernel/perf_regs.c
@@ -0,0 +1,44 @@
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+	if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
+		return 0;
+
+	/*
+	 * Compat (i.e. 32 bit) mode:
+	 * - PC has been set in the pt_regs struct in kernel_entry,
+	 * - Handle SP and LR here.
+	 */
+	if (compat_user_mode(regs)) {
+		if ((u32)idx == PERF_REG_ARM64_SP)
+			return regs->compat_sp;
+		if ((u32)idx == PERF_REG_ARM64_LR)
+			return regs->compat_lr;
+	}
+
+	return regs->regs[idx];
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_ARM64_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)
+{
+	if (is_compat_thread(task_thread_info(task)))
+		return PERF_SAMPLE_REGS_ABI_32;
+	else
+		return PERF_SAMPLE_REGS_ABI_64;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/3] ARM64: perf: add support for perf registers API
  2013-12-16 16:49 ` jean.pihet
@ 2013-12-17 11:11   ` Will Deacon
  0 siblings, 0 replies; 23+ messages in thread
From: Will Deacon @ 2013-12-17 11:11 UTC (permalink / raw)
  To: jean.pihet
  Cc: linux-kernel, linaro-kernel, Arnaldo, patches, Jiri Olsa, Ingo Molnar

Hi Jean,

On Mon, Dec 16, 2013 at 04:49:20PM +0000, jean.pihet@linaro.org wrote:
> From: Jean Pihet <jean.pihet@linaro.org>
> 
> 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.
> Compat mode is also supported.
> 
> Only the general purpose user space registers are exported, i.e.:
>  PERF_REG_ARM_X0,
>  ...
>  PERF_REG_ARM_X28,
>  PERF_REG_ARM_FP,
>  PERF_REG_ARM_LR,
>  PERF_REG_ARM_SP,
>  PERF_REG_ARM_PC
> and not the PERF_REG_ARM_V* registers.
> 
> Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm64/Kconfig                      |  2 ++
>  arch/arm64/include/asm/ptrace.h         |  1 +
>  arch/arm64/include/uapi/asm/Kbuild      |  1 +
>  arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++
>  arch/arm64/kernel/Makefile              |  1 +
>  arch/arm64/kernel/perf_regs.c           | 46 +++++++++++++++++++++++++++++++++
>  6 files changed, 91 insertions(+)
>  create mode 100644 arch/arm64/include/uapi/asm/perf_regs.h
>  create mode 100644 arch/arm64/kernel/perf_regs.c
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 88c8b6c1..f8609dc 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -28,6 +28,8 @@ config ARM64
>  	select HAVE_HW_BREAKPOINT if PERF_EVENTS
>  	select HAVE_MEMBLOCK
>  	select HAVE_PERF_EVENTS
> +	select HAVE_PERF_REGS
> +	select HAVE_PERF_USER_STACK_DUMP
>  	select IRQ_DOMAIN
>  	select MODULES_USE_ELF_RELA
>  	select NO_BOOTMEM
> diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
> index 0e7fa49..fbb0020 100644
> --- a/arch/arm64/include/asm/ptrace.h
> +++ b/arch/arm64/include/asm/ptrace.h
> @@ -68,6 +68,7 @@
>  
>  /* Architecturally defined mapping between AArch32 and AArch64 registers */
>  #define compat_usr(x)	regs[(x)]
> +#define compat_fp	regs[11]
>  #define compat_sp	regs[13]
>  #define compat_lr	regs[14]
>  #define compat_sp_hyp	regs[15]
> diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
> index e4b78bd..942376d 100644
> --- a/arch/arm64/include/uapi/asm/Kbuild
> +++ b/arch/arm64/include/uapi/asm/Kbuild
> @@ -9,6 +9,7 @@ header-y += byteorder.h
>  header-y += fcntl.h
>  header-y += hwcap.h
>  header-y += kvm_para.h
> +header-y += perf_regs.h
>  header-y += param.h
>  header-y += ptrace.h
>  header-y += setup.h
> diff --git a/arch/arm64/include/uapi/asm/perf_regs.h b/arch/arm64/include/uapi/asm/perf_regs.h
> new file mode 100644
> index 0000000..06bf360
> --- /dev/null
> +++ b/arch/arm64/include/uapi/asm/perf_regs.h
> @@ -0,0 +1,40 @@
> +#ifndef _ASM_ARM_PERF_REGS_H
> +#define _ASM_ARM_PERF_REGS_H
> +
> +enum perf_event_arm_regs {
> +	PERF_REG_ARM_X0,
> +	PERF_REG_ARM_X1,
> +	PERF_REG_ARM_X2,
> +	PERF_REG_ARM_X3,
> +	PERF_REG_ARM_X4,
> +	PERF_REG_ARM_X5,
> +	PERF_REG_ARM_X6,
> +	PERF_REG_ARM_X7,
> +	PERF_REG_ARM_X8,
> +	PERF_REG_ARM_X9,
> +	PERF_REG_ARM_X10,
> +	PERF_REG_ARM_X11,
> +	PERF_REG_ARM_X12,
> +	PERF_REG_ARM_X13,
> +	PERF_REG_ARM_X14,
> +	PERF_REG_ARM_X15,
> +	PERF_REG_ARM_X16,
> +	PERF_REG_ARM_X17,
> +	PERF_REG_ARM_X18,
> +	PERF_REG_ARM_X19,
> +	PERF_REG_ARM_X20,
> +	PERF_REG_ARM_X21,
> +	PERF_REG_ARM_X22,
> +	PERF_REG_ARM_X23,
> +	PERF_REG_ARM_X24,
> +	PERF_REG_ARM_X25,
> +	PERF_REG_ARM_X26,
> +	PERF_REG_ARM_X27,
> +	PERF_REG_ARM_X28,
> +	PERF_REG_ARM_FP,
> +	PERF_REG_ARM_LR,
> +	PERF_REG_ARM_SP,
> +	PERF_REG_ARM_PC,
> +	PERF_REG_ARM_MAX,

I think these should be PERF_REG_ARM64_* to avoid name conflicts with
arch/arm/.

> +};
> +#endif /* _ASM_ARM_PERF_REGS_H */
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 5ba2fd4..dffdd93 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -15,6 +15,7 @@ arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
>  					   sys_compat.o
>  arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
>  arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o
> +arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
>  arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
>  arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
>  arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
> diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c
> new file mode 100644
> index 0000000..d5c8fd7
> --- /dev/null
> +++ b/arch/arm64/kernel/perf_regs.c
> @@ -0,0 +1,46 @@
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/perf_event.h>
> +#include <linux/bug.h>
> +#include <asm/perf_regs.h>
> +#include <asm/ptrace.h>
> +
> +u64 perf_reg_value(struct pt_regs *regs, int idx)
> +{
> +	if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX))
> +		return 0;
> +
> +	/*
> +	 * Compat (i.e. 32 bit) mode:
> +	 * - PC has been set in the pt_regs struct in kernel_entry,
> +	 * - Handle FP, SP and LR here.
> +	 */
> +	if (compat_user_mode(regs)) {
> +		if ((u32)idx == PERF_REG_ARM_FP)

This doesn't look right to me... why would a compat task be asking for
PERF_REG_ARM_FP, where that is greater than the arch/arm/ definition of
PERF_REG_ARM_MAX?

> +			return regs->compat_fp;

Also, why are you treating FP specially? The hardware doesn't do anything
special with it.

> +		if ((u32)idx == PERF_REG_ARM_SP)
> +			return regs->compat_sp;
> +		if ((u32)idx == PERF_REG_ARM_LR)
> +			return regs->compat_lr;
> +	}
> +
> +	return regs->regs[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)
> +{
> +	if (test_tsk_thread_flag(task, TIF_32BIT))

  is_compat_thread(task_thread_info(task)) ?

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/3] ARM64: perf: add support for perf registers API
       [not found] <1387212562-8128-1-git-send-email-y>
@ 2013-12-16 16:49 ` jean.pihet
  2013-12-17 11:11   ` Will Deacon
  0 siblings, 1 reply; 23+ messages in thread
From: jean.pihet @ 2013-12-16 16:49 UTC (permalink / raw)
  To: linux-kernel, linaro-kernel, Arnaldo, Will Deacon
  Cc: patches, Jiri Olsa, Ingo Molnar, Jean Pihet

From: Jean Pihet <jean.pihet@linaro.org>

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.
Compat mode is also supported.

Only the general purpose user space registers are exported, i.e.:
 PERF_REG_ARM_X0,
 ...
 PERF_REG_ARM_X28,
 PERF_REG_ARM_FP,
 PERF_REG_ARM_LR,
 PERF_REG_ARM_SP,
 PERF_REG_ARM_PC
and not the PERF_REG_ARM_V* registers.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig                      |  2 ++
 arch/arm64/include/asm/ptrace.h         |  1 +
 arch/arm64/include/uapi/asm/Kbuild      |  1 +
 arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++
 arch/arm64/kernel/Makefile              |  1 +
 arch/arm64/kernel/perf_regs.c           | 46 +++++++++++++++++++++++++++++++++
 6 files changed, 91 insertions(+)
 create mode 100644 arch/arm64/include/uapi/asm/perf_regs.h
 create mode 100644 arch/arm64/kernel/perf_regs.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 88c8b6c1..f8609dc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -28,6 +28,8 @@ config ARM64
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS
 	select HAVE_MEMBLOCK
 	select HAVE_PERF_EVENTS
+	select HAVE_PERF_REGS
+	select HAVE_PERF_USER_STACK_DUMP
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0e7fa49..fbb0020 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -68,6 +68,7 @@
 
 /* Architecturally defined mapping between AArch32 and AArch64 registers */
 #define compat_usr(x)	regs[(x)]
+#define compat_fp	regs[11]
 #define compat_sp	regs[13]
 #define compat_lr	regs[14]
 #define compat_sp_hyp	regs[15]
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
index e4b78bd..942376d 100644
--- a/arch/arm64/include/uapi/asm/Kbuild
+++ b/arch/arm64/include/uapi/asm/Kbuild
@@ -9,6 +9,7 @@ header-y += byteorder.h
 header-y += fcntl.h
 header-y += hwcap.h
 header-y += kvm_para.h
+header-y += perf_regs.h
 header-y += param.h
 header-y += ptrace.h
 header-y += setup.h
diff --git a/arch/arm64/include/uapi/asm/perf_regs.h b/arch/arm64/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000..06bf360
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/perf_regs.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_ARM_PERF_REGS_H
+#define _ASM_ARM_PERF_REGS_H
+
+enum perf_event_arm_regs {
+	PERF_REG_ARM_X0,
+	PERF_REG_ARM_X1,
+	PERF_REG_ARM_X2,
+	PERF_REG_ARM_X3,
+	PERF_REG_ARM_X4,
+	PERF_REG_ARM_X5,
+	PERF_REG_ARM_X6,
+	PERF_REG_ARM_X7,
+	PERF_REG_ARM_X8,
+	PERF_REG_ARM_X9,
+	PERF_REG_ARM_X10,
+	PERF_REG_ARM_X11,
+	PERF_REG_ARM_X12,
+	PERF_REG_ARM_X13,
+	PERF_REG_ARM_X14,
+	PERF_REG_ARM_X15,
+	PERF_REG_ARM_X16,
+	PERF_REG_ARM_X17,
+	PERF_REG_ARM_X18,
+	PERF_REG_ARM_X19,
+	PERF_REG_ARM_X20,
+	PERF_REG_ARM_X21,
+	PERF_REG_ARM_X22,
+	PERF_REG_ARM_X23,
+	PERF_REG_ARM_X24,
+	PERF_REG_ARM_X25,
+	PERF_REG_ARM_X26,
+	PERF_REG_ARM_X27,
+	PERF_REG_ARM_X28,
+	PERF_REG_ARM_FP,
+	PERF_REG_ARM_LR,
+	PERF_REG_ARM_SP,
+	PERF_REG_ARM_PC,
+	PERF_REG_ARM_MAX,
+};
+#endif /* _ASM_ARM_PERF_REGS_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 5ba2fd4..dffdd93 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -15,6 +15,7 @@ arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o
+arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c
new file mode 100644
index 0000000..d5c8fd7
--- /dev/null
+++ b/arch/arm64/kernel/perf_regs.c
@@ -0,0 +1,46 @@
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+	if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX))
+		return 0;
+
+	/*
+	 * Compat (i.e. 32 bit) mode:
+	 * - PC has been set in the pt_regs struct in kernel_entry,
+	 * - Handle FP, SP and LR here.
+	 */
+	if (compat_user_mode(regs)) {
+		if ((u32)idx == PERF_REG_ARM_FP)
+			return regs->compat_fp;
+		if ((u32)idx == PERF_REG_ARM_SP)
+			return regs->compat_sp;
+		if ((u32)idx == PERF_REG_ARM_LR)
+			return regs->compat_lr;
+	}
+
+	return regs->regs[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)
+{
+	if (test_tsk_thread_flag(task, TIF_32BIT))
+		return PERF_SAMPLE_REGS_ABI_32;
+	else
+		return PERF_SAMPLE_REGS_ABI_64;
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-03-13 12:02 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-03 18:18 [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
2014-02-03 18:18 ` [PATCH 1/3] ARM64: perf: add support for perf registers API Jean Pihet
2014-03-13  7:27   ` [tip:perf/core] ARM64, perf: Add " tip-bot for Jean Pihet
2014-03-13 10:19     ` Catalin Marinas
2014-03-13 11:01       ` Ingo Molnar
2014-03-13 11:35         ` Catalin Marinas
2014-02-03 18:18 ` [PATCH 2/3] ARM64: perf: add support for frame pointer unwinding in compat mode Jean Pihet
2014-03-13  7:27   ` [tip:perf/core] ARM64, perf: Add " tip-bot for Jean Pihet
2014-02-03 18:18 ` [PATCH 3/3] ARM64: perf: support dwarf " Jean Pihet
2014-03-13  7:28   ` [tip:perf/core] ARM64, perf: Support " tip-bot for Jean Pihet
2014-02-12  8:47 ` [PATCH v6 0/3] perf: AARCH64 arch support Jean Pihet
2014-02-12 10:09   ` Will Deacon
2014-03-12 10:19     ` Jean Pihet
2014-03-12 17:31       ` Catalin Marinas
2014-03-13 12:02         ` Jean Pihet
  -- strict thread matches above, loose matches on Subject: below --
2013-12-30 16:25 [PATCH v4 0/3] perf: add " Jean Pihet
2013-12-30 16:25 ` [PATCH 1/3] ARM64: perf: add support for perf registers API Jean Pihet
2014-01-06 18:30   ` Will Deacon
2014-01-07  8:49     ` Jean Pihet
2014-01-15 10:30     ` Jean Pihet
2014-01-15 11:07       ` Will Deacon
2014-01-16 14:49         ` Jean Pihet
     [not found] <1387212562-8128-1-git-send-email-y>
2013-12-16 16:49 ` jean.pihet
2013-12-17 11:11   ` 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).