diff options
author | Alexander van Heukelum <heukelum@fastmail.fm> | 2008-10-04 17:12:42 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-13 04:33:41 -0400 |
commit | 3a18512db00e0eedca86e3db4d2e81f8fe0b1774 (patch) | |
tree | e452f21a8ad3001318ee75381b29280e519f09ed /arch/x86/kernel/dumpstack_32.c | |
parent | 161827903bdc124655f4cd976b9f0a5ac6ebf21c (diff) |
dumpstack: x86: add "end" parameter to valid_stack_ptr and print_context_stack
- Add "end" parameter to valid_stack_ptr and print_context_stack
- use sizeof(long) as the size of a word on the stack
Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/dumpstack_32.c')
-rw-r--r-- | arch/x86/kernel/dumpstack_32.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 4e67a005c7a1..466d55dfeb87 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -28,10 +28,16 @@ void printk_address(unsigned long address, int reliable) | |||
28 | } | 28 | } |
29 | 29 | ||
30 | static inline int valid_stack_ptr(struct thread_info *tinfo, | 30 | static inline int valid_stack_ptr(struct thread_info *tinfo, |
31 | void *p, unsigned int size) | 31 | void *p, unsigned int size, void *end) |
32 | { | 32 | { |
33 | void *t = tinfo; | 33 | void *t = tinfo; |
34 | return p > t && p <= t + THREAD_SIZE - size; | 34 | if (end) { |
35 | if (p < end && p >= (end-THREAD_SIZE)) | ||
36 | return 1; | ||
37 | else | ||
38 | return 0; | ||
39 | } | ||
40 | return p > t && p < t + THREAD_SIZE - size; | ||
35 | } | 41 | } |
36 | 42 | ||
37 | /* The form of the top of the frame on the stack */ | 43 | /* The form of the top of the frame on the stack */ |
@@ -43,16 +49,17 @@ struct stack_frame { | |||
43 | static inline unsigned long | 49 | static inline unsigned long |
44 | print_context_stack(struct thread_info *tinfo, | 50 | print_context_stack(struct thread_info *tinfo, |
45 | unsigned long *stack, unsigned long bp, | 51 | unsigned long *stack, unsigned long bp, |
46 | const struct stacktrace_ops *ops, void *data) | 52 | const struct stacktrace_ops *ops, void *data, |
53 | unsigned long *end) | ||
47 | { | 54 | { |
48 | struct stack_frame *frame = (struct stack_frame *)bp; | 55 | struct stack_frame *frame = (struct stack_frame *)bp; |
49 | 56 | ||
50 | while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) { | 57 | while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) { |
51 | unsigned long addr; | 58 | unsigned long addr; |
52 | 59 | ||
53 | addr = *stack; | 60 | addr = *stack; |
54 | if (__kernel_text_address(addr)) { | 61 | if (__kernel_text_address(addr)) { |
55 | if ((unsigned long) stack == bp + 4) { | 62 | if ((unsigned long) stack == bp + sizeof(long)) { |
56 | ops->address(data, addr, 1); | 63 | ops->address(data, addr, 1); |
57 | frame = frame->next_frame; | 64 | frame = frame->next_frame; |
58 | bp = (unsigned long) frame; | 65 | bp = (unsigned long) frame; |
@@ -96,7 +103,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
96 | 103 | ||
97 | context = (struct thread_info *) | 104 | context = (struct thread_info *) |
98 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | 105 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); |
99 | bp = print_context_stack(context, stack, bp, ops, data); | 106 | bp = print_context_stack(context, stack, bp, ops, data, NULL); |
100 | /* | 107 | /* |
101 | * Should be after the line below, but somewhere | 108 | * Should be after the line below, but somewhere |
102 | * in early boot context comes out corrupted and we | 109 | * in early boot context comes out corrupted and we |