All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Slaby <jslaby@suse.cz>
To: akpm@linux-foundation.org
Cc: torvalds@linux-foundation.org, live-patching@vger.kernel.org,
	linux-kernel@vger.kernel.org, Jiri Slaby <jslaby@suse.cz>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	x86@kernel.org, Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH 6/7] unwinder: plug in the DWARF unwinder
Date: Fri,  5 May 2017 14:21:59 +0200	[thread overview]
Message-ID: <20170505122200.31436-6-jslaby@suse.cz> (raw)
In-Reply-To: <20170505122200.31436-1-jslaby@suse.cz>

The DWARF unwinder is ready to use, so plug it into the generic
unwinding code.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/include/asm/unwind.h  | 36 +++++++++++++++-
 arch/x86/kernel/Makefile       |  4 ++
 arch/x86/kernel/unwind_dwarf.c | 95 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/kernel/unwind_dwarf.c

diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h
index e6676495b125..4c792ad0d9f9 100644
--- a/arch/x86/include/asm/unwind.h
+++ b/arch/x86/include/asm/unwind.h
@@ -12,7 +12,14 @@ struct unwind_state {
 	struct task_struct *task;
 	int graph_idx;
 	bool error;
-#ifdef CONFIG_FRAME_POINTER
+#ifdef CONFIG_DWARF_UNWIND
+	union {
+		struct pt_regs regs;
+		char regs_arr[sizeof(struct pt_regs)];
+	} u;
+	unsigned long dw_sp;
+	unsigned call_frame:1;
+#elif defined(CONFIG_FRAME_POINTER)
 	bool got_irq;
 	unsigned long *bp, *orig_sp;
 	struct pt_regs *regs;
@@ -48,7 +55,32 @@ static inline bool unwind_error(struct unwind_state *state)
 	return state->error;
 }
 
-#ifdef CONFIG_FRAME_POINTER
+#ifdef CONFIG_DWARF_UNWIND
+
+#include <asm/dwarf.h>
+
+static inline
+unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
+{
+	if (unwind_done(state))
+		return NULL;
+
+	return &DW_PC(state);
+}
+
+static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state)
+{
+	if (unwind_done(state))
+		return NULL;
+
+	/*
+	 * Should we return something? If we return the registers here, they
+	 * are output for every frame.
+	 */
+	return NULL;
+}
+
+#elif defined(CONFIG_FRAME_POINTER)
 
 static inline
 unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 4b994232cb57..604cbcbba9a5 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -124,11 +124,15 @@ obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
 obj-$(CONFIG_TRACING)			+= tracepoint.o
 obj-$(CONFIG_SCHED_MC_PRIO)		+= itmt.o
 
+ifdef CONFIG_DWARF_UNWIND
+obj-y					+= unwind_dwarf.o
+else
 ifdef CONFIG_FRAME_POINTER
 obj-y					+= unwind_frame.o
 else
 obj-y					+= unwind_guess.o
 endif
+endif
 
 ###
 # 64 bit specific files
diff --git a/arch/x86/kernel/unwind_dwarf.c b/arch/x86/kernel/unwind_dwarf.c
new file mode 100644
index 000000000000..bbcca970aca8
--- /dev/null
+++ b/arch/x86/kernel/unwind_dwarf.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016-2017 SUSE
+ *      Jiri Slaby <jirislaby@kernel.org>
+ * This code is released under the GPL v2.
+ */
+
+#include <linux/dwarf.h>
+
+unsigned long unwind_get_return_address(struct unwind_state *state)
+{
+	unsigned long *addr = unwind_get_return_address_ptr(state);
+
+	if (unwind_done(state))
+		return 0;
+
+	return ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr,
+			addr);
+}
+EXPORT_SYMBOL_GPL(unwind_get_return_address);
+
+bool unwind_next_frame(struct unwind_state *state)
+{
+	if (unwind_done(state))
+		goto bad;
+
+	if (arch_dwarf_user_mode(state))
+		goto bad;
+
+	if ((state->dw_sp & PAGE_MASK) == (DW_SP(state) & PAGE_MASK) &&
+			state->dw_sp > DW_SP(state))
+		goto bad;
+
+	if (dwarf_unwind(state) || !DW_PC(state))
+		goto bad;
+
+	state->dw_sp = DW_SP(state);
+
+	return true;
+bad:
+	state->stack_info.type = STACK_TYPE_UNKNOWN;
+	return false;
+}
+EXPORT_SYMBOL_GPL(unwind_next_frame);
+
+void __unwind_start(struct unwind_state *state, struct task_struct *task,
+		struct pt_regs *regs, unsigned long *first_frame)
+{
+	bool do_skipping = true;
+	char type;
+
+	memset(state, 0, sizeof(*state));
+	state->task = task;
+
+	if (regs) {
+		arch_dwarf_init_frame_info(state, regs);
+		type = 'R';
+	} else if (task == current) {
+		arch_dwarf_init_running(&state->u.regs);
+		type = 'C';
+#ifdef CONFIG_SMP
+	} else if (task->on_cpu) {
+		return;
+#endif
+	} else {
+		arch_dwarf_init_blocked(state);
+		type = 'B';
+		do_skipping = false;
+	}
+
+	pr_debug("%s: %c FF=%p rip=%lx (%pS) rsp=%lx rbp=%lx\n",
+			__func__, type, first_frame, DW_PC(state),
+			(void *)DW_PC(state), DW_SP(state), DW_FP(state));
+
+	get_stack_info((void *)DW_SP(state), task, &state->stack_info,
+			&state->stack_mask);
+
+	state->dw_sp = DW_SP(state);
+
+	if (arch_dwarf_user_mode(state))
+		return;
+
+	while (do_skipping) {
+		if (DW_SP(state) > (unsigned long)first_frame) {
+			pr_debug("%s: hit first=%p sp=%lx\n", __func__,
+					first_frame, DW_SP(state));
+			break;
+		}
+		if (!unwind_next_frame(state))
+			break;
+		pr_debug("%s: skipped to %pS rsp=%lx rbp=%lx\n", __func__,
+				(void *)DW_PC(state), DW_SP(state),
+				DW_FP(state));
+	}
+}
+EXPORT_SYMBOL_GPL(__unwind_start);
-- 
2.12.2

  parent reply	other threads:[~2017-05-05 12:22 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-05 12:21 [PATCH 1/7] DWARF: add option to preserve unwind info Jiri Slaby
2017-05-05 12:21 ` [PATCH 2/7] DWARF: EH-frame based stack unwinding Jiri Slaby
2017-05-05 12:21 ` [PATCH 3/7] vmlinux.lds: preserve eh_frame for DWARF unwinder Jiri Slaby
2017-05-05 12:21 ` [PATCH 4/7] DWARF: initialize structures for kernel and modules Jiri Slaby
2017-05-05 12:21 ` [PATCH 5/7] unwinder: show_stack, check also ret_addr_p's contents Jiri Slaby
2017-05-05 12:21 ` Jiri Slaby [this message]
2017-05-05 12:22 ` [PATCH 7/7] DWARF: add the config option Jiri Slaby
2017-05-05 19:57   ` Linus Torvalds
2017-05-06  7:19     ` Ingo Molnar
2017-05-10  7:46       ` Jiri Slaby
2017-05-06 14:24     ` Jiri Kosina
2017-05-07 16:55     ` Josh Poimboeuf
2017-05-07 17:59       ` Ingo Molnar
2017-05-07 18:08         ` hpa
2017-05-07 21:48           ` Josh Poimboeuf
2017-05-08  7:50             ` Vojtech Pavlik
2017-05-08 13:14               ` Josh Poimboeuf
2017-05-08  5:35       ` Andy Lutomirski
2017-05-08  6:15         ` Ingo Molnar
2017-05-08 14:40         ` Josh Poimboeuf
2017-05-08 18:57           ` hpa
2017-05-09  0:21       ` Andy Lutomirski
2017-05-09  1:38         ` Josh Poimboeuf
2017-05-09  2:31           ` Andy Lutomirski
2017-05-09  3:38             ` Josh Poimboeuf
2017-05-09 10:00               ` hpa
2017-05-09 14:58                 ` Josh Poimboeuf
2017-05-09 16:46                   ` H.J. Lu
2017-05-10  8:15                 ` Jiri Slaby
2017-05-10 13:09                   ` Josh Poimboeuf
2017-05-10 16:23                     ` H.J. Lu
2017-05-09 18:47       ` Jiri Kosina
2017-05-09 19:22         ` Josh Poimboeuf
2017-05-10  8:32           ` Jiri Slaby
2017-05-10 13:13             ` Josh Poimboeuf
2017-05-23  7:07             ` Peter Zijlstra
2017-05-23  7:27               ` Ingo Molnar
2017-05-19 20:53       ` Josh Poimboeuf
2017-05-19 20:57         ` H. Peter Anvin
2017-05-19 20:59         ` H. Peter Anvin
2017-05-19 21:29           ` Josh Poimboeuf
2017-05-19 21:35             ` Josh Poimboeuf
2017-05-20  5:23               ` Andy Lutomirski
2017-05-20 16:20                 ` Josh Poimboeuf
2017-05-20 17:19                   ` Josh Poimboeuf
2017-05-20 20:01                   ` H.J. Lu
2017-05-20 21:58                     ` Andy Lutomirski
2017-05-20 22:20                       ` H.J. Lu
2017-05-22 11:34                         ` Jiri Kosina
2017-05-22 14:39                           ` H.J. Lu
2017-05-22 21:07                     ` H. Peter Anvin
2017-05-22 21:37                       ` H. Peter Anvin
2017-05-22 22:11                         ` Josh Poimboeuf
2017-05-20 20:16                 ` Linus Torvalds
2017-05-20 21:56                   ` Andy Lutomirski
2017-05-20 23:00                     ` Linus Torvalds
2017-05-20 23:29                       ` Linus Torvalds
2017-05-26  6:54               ` Jiri Slaby
2017-05-26 11:29                 ` Jiri Slaby
2017-05-26 12:14                   ` Josh Poimboeuf
2017-05-22 11:12             ` Ingo Molnar
2017-05-22 21:16               ` H. Peter Anvin
2017-05-22 23:23                 ` Jiri Kosina
2017-05-23  5:49                 ` Ingo Molnar
2017-05-26 19:16                   ` hpa
2017-05-28  9:12                     ` Ingo Molnar
2017-05-10  7:39     ` Jiri Slaby
2017-05-10 12:42       ` Josh Poimboeuf
2017-05-10 12:47         ` Jiri Slaby
2017-05-10 18:11       ` Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170505122200.31436-6-jslaby@suse.cz \
    --to=jslaby@suse.cz \
    --cc=akpm@linux-foundation.org \
    --cc=hpa@zytor.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.