All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH][RFC] x86: oprofile 32bit stack traces on 64bit kernel
@ 2008-02-05 16:20 Jason Wessel
  2008-02-07 16:57 ` Arjan van de Ven
  0 siblings, 1 reply; 2+ messages in thread
From: Jason Wessel @ 2008-02-05 16:20 UTC (permalink / raw)
  To: lkml, phil.el; +Cc: oprofile-list


There are multiple ways to write the same code, hence the reason this
is listed as an RFC patch.  I wanted to provide a working fix to
account for the case of executing 32 bit and 64 bit user space code on
a 64 bit kernel.

-----CLIP HERE-------

Allow oprofile's backtrace to work on a 32bit user space thread when
running on a 64bit kernel.

Signed-off-by: Jason Wessel <jason.wessel@windriver.com>

---
 arch/x86/oprofile/backtrace.c |   40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

--- a/arch/x86/oprofile/backtrace.c
+++ b/arch/x86/oprofile/backtrace.c
@@ -52,6 +52,39 @@ struct frame_head {
 	unsigned long ret;
 } __attribute__((packed));
 
+
+#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
+struct frame_head32 {
+	unsigned int ebp;
+	unsigned int ret;
+} __attribute__((packed));
+
+static struct frame_head *
+dump_user_backtrace32(struct frame_head * head)
+{
+	struct frame_head32 bufhead[2];
+
+	/* Also check accessibility of one struct frame_head beyond */
+	if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
+		return NULL;
+	if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
+		return NULL;
+	/* In a 32bit user space on a 64bit kernel the frame pointer and
+	 * PC are not at the same place as in the 64 registers.  This
+	 * requires some casting and checks of the 32bit register values
+	 * back to 64 pit pointers.
+	 */
+	oprofile_add_trace(bufhead[0].ret);
+
+	/* frame pointers should strictly progress back up the stack
+	 * (towards higher addresses) */
+	if (head >= (struct frame_head *)((unsigned long)bufhead[0].ebp))
+		return NULL;
+
+	return (struct frame_head *)((unsigned long)bufhead[0].ebp);
+}
+#endif
+
 static struct frame_head *
 dump_user_backtrace(struct frame_head * head)
 {
@@ -85,7 +118,12 @@ x86_backtrace(struct pt_regs * const reg
 				   &backtrace_ops, &depth);
 		return;
 	}
-
+#if defined(CONFIG_X86_64) && defined(CONFIG_IA32_EMULATION)
+	if (test_thread_flag(TIF_32BIT))
+		while (depth-- && head)
+			head = dump_user_backtrace32(head);
+	else
+#endif
 	while (depth-- && head)
 		head = dump_user_backtrace(head);
 }

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

end of thread, other threads:[~2008-02-07 16:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-05 16:20 [PATCH][RFC] x86: oprofile 32bit stack traces on 64bit kernel Jason Wessel
2008-02-07 16:57 ` Arjan van de Ven

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.