diff options
-rw-r--r-- | arch/mips/kernel/stacktrace.c | 22 | ||||
-rw-r--r-- | arch/s390/kernel/stacktrace.c | 18 | ||||
-rw-r--r-- | arch/sh/kernel/stacktrace.c | 9 | ||||
-rw-r--r-- | arch/sparc64/kernel/stacktrace.c | 20 | ||||
-rw-r--r-- | arch/x86_64/kernel/stacktrace.c | 8 | ||||
-rw-r--r-- | include/linux/stacktrace.h | 6 | ||||
-rw-r--r-- | kernel/lockdep.c | 3 | ||||
-rw-r--r-- | lib/fault-inject.c | 3 |
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 | ||
34 | static void save_context_stack(struct stack_trace *trace, | 34 | static 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 | */ |
67 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | 66 | void 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 | ||
62 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | 62 | void 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 | */ |
20 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | 20 | void 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 | ||
6 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | 6 | void 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 | ||
22 | static int save_stack_stack(void *data, char *name) | 22 | static 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 | ||
28 | static void save_stack_address(void *data, unsigned long addr) | 27 | static 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 | */ |
49 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | 48 | void 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 | } |
55 | EXPORT_SYMBOL(save_stack_trace); | 54 | EXPORT_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 | ||
12 | extern void save_stack_trace(struct stack_trace *trace, | 11 | extern void save_stack_trace(struct stack_trace *trace); |
13 | struct task_struct *task); | ||
14 | 12 | ||
15 | extern void print_stack_trace(struct stack_trace *trace, int spaces); | 13 | extern 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) |