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
next prev 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 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).