All of lore.kernel.org
 help / color / mirror / Atom feed
From: Josh Poimboeuf <jpoimboe@redhat.com>
To: Jiri Kosina <jikos@kernel.org>, Jessica Yu <jeyu@redhat.com>,
	Miroslav Benes <mbenes@suse.cz>
Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org,
	Vojtech Pavlik <vojtech@suse.com>
Subject: [RFC PATCH v1.9 06/14] x86: add error handling to dump_trace()
Date: Fri, 25 Mar 2016 14:34:53 -0500	[thread overview]
Message-ID: <6b02b97ca6dc29008b7d2cc91ca707d51fe58466.1458933243.git.jpoimboe@redhat.com> (raw)
In-Reply-To: <cover.1458933243.git.jpoimboe@redhat.com>

In preparation for being able to determine whether a given stack trace
is reliable, allow the stacktrace_ops functions to propagate errors to
dump_trace().

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 arch/x86/include/asm/stacktrace.h | 36 +++++++++++++++-----------
 arch/x86/kernel/dumpstack.c       | 31 +++++++++++------------
 arch/x86/kernel/dumpstack_32.c    | 22 ++++++++++------
 arch/x86/kernel/dumpstack_64.c    | 53 ++++++++++++++++++++++++++-------------
 4 files changed, 87 insertions(+), 55 deletions(-)

diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index 7c247e7..a64523f3 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -14,26 +14,32 @@ extern int kstack_depth_to_print;
 struct thread_info;
 struct stacktrace_ops;
 
-typedef unsigned long (*walk_stack_t)(struct thread_info *tinfo,
-				      unsigned long *stack,
-				      unsigned long bp,
-				      const struct stacktrace_ops *ops,
-				      void *data,
-				      unsigned long *end,
-				      int *graph);
-
-extern unsigned long
+typedef int (*walk_stack_t)(struct thread_info *tinfo,
+			    unsigned long *stack,
+			    unsigned long *bp,
+			    const struct stacktrace_ops *ops,
+			    void *data,
+			    unsigned long *end,
+			    int *graph);
+
+extern int
 print_context_stack(struct thread_info *tinfo,
-		    unsigned long *stack, unsigned long bp,
+		    unsigned long *stack, unsigned long *bp,
 		    const struct stacktrace_ops *ops, void *data,
 		    unsigned long *end, int *graph);
 
-extern unsigned long
+extern int
 print_context_stack_bp(struct thread_info *tinfo,
-		       unsigned long *stack, unsigned long bp,
+		       unsigned long *stack, unsigned long *bp,
 		       const struct stacktrace_ops *ops, void *data,
 		       unsigned long *end, int *graph);
 
+extern int
+print_context_stack_reliable(struct thread_info *tinfo,
+			     unsigned long *stack, unsigned long *bp,
+			     const struct stacktrace_ops *ops, void *data,
+			     unsigned long *end, int *graph);
+
 /* Generic stack tracer with callbacks */
 
 struct stacktrace_ops {
@@ -43,9 +49,9 @@ struct stacktrace_ops {
 	walk_stack_t	walk_stack;
 };
 
-void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
-		unsigned long *stack, unsigned long bp,
-		const struct stacktrace_ops *ops, void *data);
+int dump_trace(struct task_struct *tsk, struct pt_regs *regs,
+	       unsigned long *stack, unsigned long bp,
+	       const struct stacktrace_ops *ops, void *data);
 
 #ifdef CONFIG_X86_32
 #define STACKSLOTS_PER_LINE 8
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 8efa57a..3b10518 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -92,23 +92,22 @@ static inline int valid_stack_ptr(struct thread_info *tinfo,
 	return p > t && p < t + THREAD_SIZE - size;
 }
 
-unsigned long
-print_context_stack(struct thread_info *tinfo,
-		unsigned long *stack, unsigned long bp,
-		const struct stacktrace_ops *ops, void *data,
-		unsigned long *end, int *graph)
+int print_context_stack(struct thread_info *tinfo,
+			unsigned long *stack, unsigned long *bp,
+			const struct stacktrace_ops *ops, void *data,
+			unsigned long *end, int *graph)
 {
-	struct stack_frame *frame = (struct stack_frame *)bp;
+	struct stack_frame *frame = (struct stack_frame *)*bp;
 
 	while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
 		unsigned long addr;
 
 		addr = *stack;
 		if (__kernel_text_address(addr)) {
-			if ((unsigned long) stack == bp + sizeof(long)) {
+			if ((unsigned long) stack == *bp + sizeof(long)) {
 				ops->address(data, addr, 1);
 				frame = frame->next_frame;
-				bp = (unsigned long) frame;
+				*bp = (unsigned long) frame;
 			} else {
 				ops->address(data, addr, 0);
 			}
@@ -116,17 +115,16 @@ print_context_stack(struct thread_info *tinfo,
 		}
 		stack++;
 	}
-	return bp;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(print_context_stack);
 
-unsigned long
-print_context_stack_bp(struct thread_info *tinfo,
-		       unsigned long *stack, unsigned long bp,
-		       const struct stacktrace_ops *ops, void *data,
-		       unsigned long *end, int *graph)
+int print_context_stack_bp(struct thread_info *tinfo,
+			   unsigned long *stack, unsigned long *bp,
+			   const struct stacktrace_ops *ops, void *data,
+			   unsigned long *end, int *graph)
 {
-	struct stack_frame *frame = (struct stack_frame *)bp;
+	struct stack_frame *frame = (struct stack_frame *)*bp;
 	unsigned long *ret_addr = &frame->return_address;
 
 	while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
@@ -142,7 +140,8 @@ print_context_stack_bp(struct thread_info *tinfo,
 		print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
 	}
 
-	return (unsigned long)frame;
+	*bp = (unsigned long)frame;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(print_context_stack_bp);
 
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 464ffd6..e710bab 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -38,13 +38,14 @@ static void *is_softirq_stack(unsigned long *stack, int cpu)
 	return is_irq_stack(stack, irq);
 }
 
-void dump_trace(struct task_struct *task, struct pt_regs *regs,
-		unsigned long *stack, unsigned long bp,
-		const struct stacktrace_ops *ops, void *data)
+int dump_trace(struct task_struct *task, struct pt_regs *regs,
+	       unsigned long *stack, unsigned long bp,
+	       const struct stacktrace_ops *ops, void *data)
 {
 	const unsigned cpu = get_cpu();
 	int graph = 0;
 	u32 *prev_esp;
+	int ret;
 
 	if (!task)
 		task = current;
@@ -69,8 +70,10 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 			end_stack = is_softirq_stack(stack, cpu);
 
 		context = task_thread_info(task);
-		bp = ops->walk_stack(context, stack, bp, ops, data,
-				     end_stack, &graph);
+		ret = ops->walk_stack(context, stack, &bp, ops, data,
+				      end_stack, &graph);
+		if (ret)
+			goto out;
 
 		/* Stop if not on irq stack */
 		if (!end_stack)
@@ -82,11 +85,16 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 		if (!stack)
 			break;
 
-		if (ops->stack(data, "IRQ") < 0)
-			break;
+		ret = ops->stack(data, "IRQ");
+		if (ret)
+			goto out;
+
 		touch_nmi_watchdog();
 	}
+
+out:
 	put_cpu();
+	return ret;
 }
 EXPORT_SYMBOL(dump_trace);
 
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 5f1c626..0c810ba 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -148,9 +148,9 @@ analyze_stack(int cpu, struct task_struct *task, unsigned long *stack,
  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
  */
 
-void dump_trace(struct task_struct *task, struct pt_regs *regs,
-		unsigned long *stack, unsigned long bp,
-		const struct stacktrace_ops *ops, void *data)
+int dump_trace(struct task_struct *task, struct pt_regs *regs,
+	       unsigned long *stack, unsigned long bp,
+	       const struct stacktrace_ops *ops, void *data)
 {
 	const unsigned cpu = get_cpu();
 	struct thread_info *tinfo;
@@ -159,6 +159,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 	unsigned used = 0;
 	int graph = 0;
 	int done = 0;
+	int ret;
 
 	if (!task)
 		task = current;
@@ -198,13 +199,18 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 			break;
 
 		case STACK_IS_EXCEPTION:
-
-			if (ops->stack(data, id) < 0)
-				break;
-
-			bp = ops->walk_stack(tinfo, stack, bp, ops,
-					     data, stack_end, &graph);
-			ops->stack(data, "<EOE>");
+			ret = ops->stack(data, id);
+			if (ret)
+				goto out;
+
+			ret = ops->walk_stack(tinfo, stack, &bp, ops, data,
+					      stack_end, &graph);
+			if (ret)
+				goto out;
+
+			ret = ops->stack(data, "<EOE>");
+			if (ret)
+				goto out;
 			/*
 			 * We link to the next stack via the
 			 * second-to-last pointer (index -2 to end) in the
@@ -215,11 +221,15 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 			break;
 
 		case STACK_IS_IRQ:
+			ret = ops->stack(data, "IRQ");
+			if (ret)
+				goto out;
+
+			ret = ops->walk_stack(tinfo, stack, &bp, ops, data,
+					      stack_end, &graph);
+			if (ret)
+				goto out;
 
-			if (ops->stack(data, "IRQ") < 0)
-				break;
-			bp = ops->walk_stack(tinfo, stack, bp,
-				     ops, data, stack_end, &graph);
 			/*
 			 * We link to the next stack (which would be
 			 * the process stack normally) the last
@@ -227,12 +237,18 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 			 */
 			stack = (unsigned long *) (stack_end[-1]);
 			irq_stack = NULL;
-			ops->stack(data, "EOI");
+
+			ret = ops->stack(data, "EOI");
+			if (ret)
+				goto out;
+
 			done = 0;
 			break;
 
 		case STACK_IS_UNKNOWN:
-			ops->stack(data, "UNK");
+			ret = ops->stack(data, "UNK");
+			if (ret)
+				goto out;
 			break;
 		}
 	}
@@ -240,8 +256,11 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 	/*
 	 * This handles the process stack:
 	 */
-	bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph);
+	ret = ops->walk_stack(tinfo, stack, &bp, ops, data, NULL, &graph);
+
+out:
 	put_cpu();
+	return ret;
 }
 EXPORT_SYMBOL(dump_trace);
 
-- 
2.4.3

  parent reply	other threads:[~2016-03-25 19:36 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-25 19:34 [RFC PATCH v1.9 00/14] livepatch: hybrid consistency model Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 01/14] x86/asm/head: cleanup initial stack variable Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 02/14] x86/asm/head: use a common function for starting CPUs Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 03/14] x86/asm/head: standardize the bottom of the stack for idle tasks Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 04/14] x86: move _stext marker before head code Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 05/14] sched: horrible way to detect whether a task has been preempted Josh Poimboeuf
2016-04-06 13:06   ` Petr Mladek
2016-04-06 16:33     ` Josh Poimboeuf
2016-04-07  9:47       ` Petr Mladek
2016-04-07 14:34         ` Josh Poimboeuf
2016-04-08  8:07           ` Petr Mladek
2016-04-08 14:34             ` Josh Poimboeuf
2016-04-07 21:15   ` Jessica Yu
2016-04-07 21:37     ` Jiri Kosina
2016-04-07 22:35       ` Josh Poimboeuf
2016-04-07 22:53         ` Jiri Kosina
2016-04-07 23:15       ` Jessica Yu
2016-04-08  7:05         ` Jiri Kosina
2016-04-08  8:03           ` Petr Mladek
2016-04-08 14:31             ` Josh Poimboeuf
2016-04-11  8:38               ` Petr Mladek
2016-03-25 19:34 ` Josh Poimboeuf [this message]
2016-03-25 19:34 ` [RFC PATCH v1.9 07/14] x86/stacktrace: add function for detecting reliable stack traces Josh Poimboeuf
2016-03-31 13:03   ` Miroslav Benes
2016-04-04 17:54     ` Josh Poimboeuf
2016-04-11 14:16       ` Jiri Slaby
2016-04-12 15:56         ` Josh Poimboeuf
2016-06-09  8:31           ` Jiri Slaby
2016-06-13 21:58             ` Josh Poimboeuf
2016-12-01 20:28               ` Jiri Slaby
2016-12-01 20:59                 ` Josh Poimboeuf
2017-01-17 13:08                   ` Jiri Slaby
2016-04-04 15:55   ` Petr Mladek
2016-04-04 17:58     ` Josh Poimboeuf
2016-04-07 11:55   ` Petr Mladek
2016-04-07 14:46     ` Josh Poimboeuf
2016-04-08  8:24       ` Petr Mladek
2016-04-11  3:29   ` Jessica Yu
2016-03-25 19:34 ` [RFC PATCH v1.9 08/14] livepatch: separate enabled and patched states Josh Poimboeuf
2016-04-11  3:31   ` Jessica Yu
2016-04-12 14:44   ` [RFC PATCH v1.9 08/14] " Chris J Arges
2016-04-12 17:16     ` Josh Poimboeuf
2016-04-12 17:35       ` Chris J Arges
2016-04-12 18:25         ` Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 09/14] livepatch: remove unnecessary object loaded check Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 10/14] livepatch: move patching functions into patch.c Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 11/14] livepatch: store function sizes Josh Poimboeuf
2016-03-25 19:34 ` [RFC PATCH v1.9 12/14] livepatch: create per-task consistency model Josh Poimboeuf
2016-03-31 13:12   ` Miroslav Benes
2016-04-04 18:21     ` Josh Poimboeuf
2016-04-04 18:27       ` Vojtech Pavlik
2016-04-04 18:33         ` Josh Poimboeuf
2016-04-05 11:36           ` Vojtech Pavlik
2016-04-05 13:53             ` Josh Poimboeuf
2016-04-05 17:32   ` Minfei Huang
2016-04-05 21:17     ` Josh Poimboeuf
2016-04-14  9:25   ` Miroslav Benes
2016-04-14 16:39     ` Josh Poimboeuf
2016-04-15  9:17       ` Miroslav Benes
2016-03-25 19:35 ` [RFC PATCH v1.9 13/14] livepatch: add /proc/<pid>/patch_status Josh Poimboeuf
2016-03-31  9:33   ` Jiri Slaby
2016-03-31  9:40     ` Jiri Slaby
2016-04-04 16:56     ` Josh Poimboeuf
2016-03-25 19:35 ` [RFC PATCH v1.9 14/14] livepatch: update task universe when exiting kernel Josh Poimboeuf
2016-04-14  8:47   ` Miroslav Benes
2016-04-14  8:50     ` Miroslav Benes
2016-04-14 13:39       ` Josh Poimboeuf
2016-04-18 15:01         ` [RFC PATCH 0/2] s390/klp: s390 support Miroslav Benes
2016-04-18 15:01           ` [RFC PATCH 1/2] s390: livepatch, reorganize TIF bits Miroslav Benes
2016-04-18 15:01           ` [RFC PATCH 2/2] s390/klp: update task universe when exiting kernel Miroslav Benes
2016-04-18 15:17           ` [RFC PATCH 0/2] s390/klp: s390 support Josh Poimboeuf
2016-04-14 13:23     ` [RFC PATCH v1.9 14/14] livepatch: update task universe when exiting kernel Josh Poimboeuf
2016-03-31 12:54 ` [RFC PATCH v1.9 00/14] livepatch: hybrid consistency model Miroslav Benes
2016-04-04 17:03   ` Josh Poimboeuf
2016-04-05 14:24     ` Miroslav Benes
2016-04-05 14:34       ` Josh Poimboeuf
2016-04-05 14:53         ` Miroslav Benes
2016-04-01 13:34 ` Miroslav Benes
2016-04-01 13:39 ` Petr Mladek
2016-04-01 15:38   ` Petr Mladek
2016-04-05 13:44   ` Josh Poimboeuf
2016-04-06  8:15     ` Petr Mladek
2016-04-28 18:53     ` Josh Poimboeuf
2016-06-09 14:20       ` Petr Mladek
2016-04-07 12:10 ` Petr Mladek
2016-04-07 15:08   ` Josh Poimboeuf
2016-04-07 15:47     ` Jiri Kosina
2016-04-07 18:03       ` Josh Poimboeuf
2016-04-07 18:33         ` Jiri Kosina

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=6b02b97ca6dc29008b7d2cc91ca707d51fe58466.1458933243.git.jpoimboe@redhat.com \
    --to=jpoimboe@redhat.com \
    --cc=jeyu@redhat.com \
    --cc=jikos@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=vojtech@suse.com \
    /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.