aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/stacktrace.c22
-rw-r--r--arch/s390/kernel/stacktrace.c18
-rw-r--r--arch/sh/kernel/stacktrace.c9
-rw-r--r--arch/sparc64/kernel/stacktrace.c20
-rw-r--r--arch/x86_64/kernel/stacktrace.c8
-rw-r--r--include/linux/stacktrace.h6
-rw-r--r--kernel/lockdep.c3
-rw-r--r--lib/fault-inject.c3
8 files changed, 28 insertions, 61 deletions
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
index a586aba337a7..ebd9db8d1ece 100644
--- a/arch/mips/kernel/stacktrace.c
+++ b/arch/mips/kernel/stacktrace.c
@@ -31,8 +31,7 @@ static void save_raw_context_stack(struct stack_trace *trace,
31 } 31 }
32} 32}
33 33
34static void save_context_stack(struct stack_trace *trace, 34static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs)
35 struct task_struct *task, struct pt_regs *regs)
36{ 35{
37 unsigned long sp = regs->regs[29]; 36 unsigned long sp = regs->regs[29];
38#ifdef CONFIG_KALLSYMS 37#ifdef CONFIG_KALLSYMS
@@ -41,7 +40,7 @@ static void save_context_stack(struct stack_trace *trace,
41 40
42 if (raw_show_trace || !__kernel_text_address(pc)) { 41 if (raw_show_trace || !__kernel_text_address(pc)) {
43 unsigned long stack_page = 42 unsigned long stack_page =
44 (unsigned long)task_stack_page(task); 43 (unsigned long)task_stack_page(current);
45 if (stack_page && sp >= stack_page && 44 if (stack_page && sp >= stack_page &&
46 sp <= stack_page + THREAD_SIZE - 32) 45 sp <= stack_page + THREAD_SIZE - 32)
47 save_raw_context_stack(trace, sp); 46 save_raw_context_stack(trace, sp);
@@ -54,7 +53,7 @@ static void save_context_stack(struct stack_trace *trace,
54 trace->entries[trace->nr_entries++] = pc; 53 trace->entries[trace->nr_entries++] = pc;
55 if (trace->nr_entries >= trace->max_entries) 54 if (trace->nr_entries >= trace->max_entries)
56 break; 55 break;
57 pc = unwind_stack(task, &sp, pc, &ra); 56 pc = unwind_stack(current, &sp, pc, &ra);
58 } while (pc); 57 } while (pc);
59#else 58#else
60 save_raw_context_stack(trace, sp); 59 save_raw_context_stack(trace, sp);
@@ -64,22 +63,13 @@ static void save_context_stack(struct stack_trace *trace,
64/* 63/*
65 * Save stack-backtrace addresses into a stack_trace buffer. 64 * Save stack-backtrace addresses into a stack_trace buffer.
66 */ 65 */
67void save_stack_trace(struct stack_trace *trace, struct task_struct *task) 66void save_stack_trace(struct stack_trace *trace)
68{ 67{
69 struct pt_regs dummyregs; 68 struct pt_regs dummyregs;
70 struct pt_regs *regs = &dummyregs; 69 struct pt_regs *regs = &dummyregs;
71 70
72 WARN_ON(trace->nr_entries || !trace->max_entries); 71 WARN_ON(trace->nr_entries || !trace->max_entries);
73 72
74 if (task && task != current) { 73 prepare_frametrace(regs);
75 regs->regs[29] = task->thread.reg29; 74 save_context_stack(trace, regs);
76 regs->regs[31] = 0;
77 regs->cp0_epc = task->thread.reg31;
78 } else {
79 if (!task)
80 task = current;
81 prepare_frametrace(regs);
82 }
83
84 save_context_stack(trace, task, regs);
85} 75}
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index 2e5c65a1863e..515ff9011dd7 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -59,7 +59,7 @@ static unsigned long save_context_stack(struct stack_trace *trace,
59 } 59 }
60} 60}
61 61
62void save_stack_trace(struct stack_trace *trace, struct task_struct *task) 62void save_stack_trace(struct stack_trace *trace)
63{ 63{
64 register unsigned long sp asm ("15"); 64 register unsigned long sp asm ("15");
65 unsigned long orig_sp, new_sp; 65 unsigned long orig_sp, new_sp;
@@ -69,20 +69,16 @@ void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
69 new_sp = save_context_stack(trace, &trace->skip, orig_sp, 69 new_sp = save_context_stack(trace, &trace->skip, orig_sp,
70 S390_lowcore.panic_stack - PAGE_SIZE, 70 S390_lowcore.panic_stack - PAGE_SIZE,
71 S390_lowcore.panic_stack); 71 S390_lowcore.panic_stack);
72 if ((new_sp != orig_sp) && !trace->all_contexts) 72 if (new_sp != orig_sp)
73 return; 73 return;
74 new_sp = save_context_stack(trace, &trace->skip, new_sp, 74 new_sp = save_context_stack(trace, &trace->skip, new_sp,
75 S390_lowcore.async_stack - ASYNC_SIZE, 75 S390_lowcore.async_stack - ASYNC_SIZE,
76 S390_lowcore.async_stack); 76 S390_lowcore.async_stack);
77 if ((new_sp != orig_sp) && !trace->all_contexts) 77 if (new_sp != orig_sp)
78 return; 78 return;
79 if (task) 79
80 save_context_stack(trace, &trace->skip, new_sp, 80 save_context_stack(trace, &trace->skip, new_sp,
81 (unsigned long) task_stack_page(task), 81 S390_lowcore.thread_info,
82 (unsigned long) task_stack_page(task) + THREAD_SIZE); 82 S390_lowcore.thread_info + THREAD_SIZE);
83 else
84 save_context_stack(trace, &trace->skip, new_sp,
85 S390_lowcore.thread_info,
86 S390_lowcore.thread_info + THREAD_SIZE);
87 return; 83 return;
88} 84}
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
index 0d5268afe80f..4bdd2f83535d 100644
--- a/arch/sh/kernel/stacktrace.c
+++ b/arch/sh/kernel/stacktrace.c
@@ -19,14 +19,7 @@
19 */ 19 */
20void save_stack_trace(struct stack_trace *trace, struct task_struct *task) 20void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
21{ 21{
22 unsigned long *sp; 22 unsigned long *sp = (unsigned long *)current_stack_pointer;
23
24 if (!task)
25 task = current;
26 if (task == current)
27 sp = (unsigned long *)current_stack_pointer;
28 else
29 sp = (unsigned long *)task->thread.sp;
30 23
31 while (!kstack_end(sp)) { 24 while (!kstack_end(sp)) {
32 unsigned long addr = *sp++; 25 unsigned long addr = *sp++;
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c
index c4d15f2762b9..47f92a59be18 100644
--- a/arch/sparc64/kernel/stacktrace.c
+++ b/arch/sparc64/kernel/stacktrace.c
@@ -3,22 +3,16 @@
3#include <linux/thread_info.h> 3#include <linux/thread_info.h>
4#include <asm/ptrace.h> 4#include <asm/ptrace.h>
5 5
6void save_stack_trace(struct stack_trace *trace, struct task_struct *task) 6void save_stack_trace(struct stack_trace *trace)
7{ 7{
8 unsigned long ksp, fp, thread_base; 8 unsigned long ksp, fp, thread_base;
9 struct thread_info *tp; 9 struct thread_info *tp = task_thread_info(current);
10 10
11 if (!task) 11 flushw_all();
12 task = current; 12 __asm__ __volatile__(
13 tp = task_thread_info(task); 13 "mov %%fp, %0"
14 if (task == current) { 14 : "=r" (ksp)
15 flushw_all(); 15 );
16 __asm__ __volatile__(
17 "mov %%fp, %0"
18 : "=r" (ksp)
19 );
20 } else
21 ksp = tp->ksp;
22 16
23 fp = ksp + STACK_BIAS; 17 fp = ksp + STACK_BIAS;
24 thread_base = (unsigned long) tp; 18 thread_base = (unsigned long) tp;
diff --git a/arch/x86_64/kernel/stacktrace.c b/arch/x86_64/kernel/stacktrace.c
index 65ac2c6b34a6..cb9109113584 100644
--- a/arch/x86_64/kernel/stacktrace.c
+++ b/arch/x86_64/kernel/stacktrace.c
@@ -21,8 +21,7 @@ save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
21 21
22static int save_stack_stack(void *data, char *name) 22static int save_stack_stack(void *data, char *name)
23{ 23{
24 struct stack_trace *trace = (struct stack_trace *)data; 24 return -1;
25 return trace->all_contexts ? 0 : -1;
26} 25}
27 26
28static void save_stack_address(void *data, unsigned long addr) 27static void save_stack_address(void *data, unsigned long addr)
@@ -46,11 +45,10 @@ static struct stacktrace_ops save_stack_ops = {
46/* 45/*
47 * Save stack-backtrace addresses into a stack_trace buffer. 46 * Save stack-backtrace addresses into a stack_trace buffer.
48 */ 47 */
49void save_stack_trace(struct stack_trace *trace, struct task_struct *task) 48void save_stack_trace(struct stack_trace *trace)
50{ 49{
51 dump_trace(task, NULL, NULL, &save_stack_ops, trace); 50 dump_trace(current, NULL, NULL, &save_stack_ops, trace);
52 if (trace->nr_entries < trace->max_entries) 51 if (trace->nr_entries < trace->max_entries)
53 trace->entries[trace->nr_entries++] = ULONG_MAX; 52 trace->entries[trace->nr_entries++] = ULONG_MAX;
54} 53}
55EXPORT_SYMBOL(save_stack_trace); 54EXPORT_SYMBOL(save_stack_trace);
56
diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h
index 50e2b01e517c..1d2b084c0185 100644
--- a/include/linux/stacktrace.h
+++ b/include/linux/stacktrace.h
@@ -6,15 +6,13 @@ struct stack_trace {
6 unsigned int nr_entries, max_entries; 6 unsigned int nr_entries, max_entries;
7 unsigned long *entries; 7 unsigned long *entries;
8 int skip; /* input argument: How many entries to skip */ 8 int skip; /* input argument: How many entries to skip */
9 int all_contexts; /* input argument: if true do than one stack */
10}; 9};
11 10
12extern void save_stack_trace(struct stack_trace *trace, 11extern void save_stack_trace(struct stack_trace *trace);
13 struct task_struct *task);
14 12
15extern void print_stack_trace(struct stack_trace *trace, int spaces); 13extern void print_stack_trace(struct stack_trace *trace, int spaces);
16#else 14#else
17# define save_stack_trace(trace, task) do { } while (0) 15# define save_stack_trace(trace) do { } while (0)
18# define print_stack_trace(trace) do { } while (0) 16# define print_stack_trace(trace) do { } while (0)
19#endif 17#endif
20 18
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 7065a687ac54..c1e308a080b8 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -257,9 +257,8 @@ static int save_trace(struct stack_trace *trace)
257 trace->entries = stack_trace + nr_stack_trace_entries; 257 trace->entries = stack_trace + nr_stack_trace_entries;
258 258
259 trace->skip = 3; 259 trace->skip = 3;
260 trace->all_contexts = 0;
261 260
262 save_stack_trace(trace, NULL); 261 save_stack_trace(trace);
263 262
264 trace->max_entries = trace->nr_entries; 263 trace->max_entries = trace->nr_entries;
265 264
diff --git a/lib/fault-inject.c b/lib/fault-inject.c
index 0fabd12c39d7..b18fc2ff9ffe 100644
--- a/lib/fault-inject.c
+++ b/lib/fault-inject.c
@@ -72,9 +72,8 @@ static bool fail_stacktrace(struct fault_attr *attr)
72 trace.entries = entries; 72 trace.entries = entries;
73 trace.max_entries = depth; 73 trace.max_entries = depth;
74 trace.skip = 1; 74 trace.skip = 1;
75 trace.all_contexts = 0;
76 75
77 save_stack_trace(&trace, NULL); 76 save_stack_trace(&trace);
78 for (n = 0; n < trace.nr_entries; n++) { 77 for (n = 0; n < trace.nr_entries; n++) {
79 if (attr->reject_start <= entries[n] && 78 if (attr->reject_start <= entries[n] &&
80 entries[n] < attr->reject_end) 79 entries[n] < attr->reject_end)