aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r--arch/i386/kernel/traps.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index cfffe3dd9e83..47b0bef335bd 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -100,36 +100,45 @@ asmlinkage void machine_check(void);
100int kstack_depth_to_print = 24; 100int kstack_depth_to_print = 24;
101static unsigned int code_bytes = 64; 101static unsigned int code_bytes = 64;
102 102
103static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) 103static inline int valid_stack_ptr(struct thread_info *tinfo, void *p, unsigned size)
104{ 104{
105 return p > (void *)tinfo && 105 return p > (void *)tinfo &&
106 p < (void *)tinfo + THREAD_SIZE - 3; 106 p <= (void *)tinfo + THREAD_SIZE - size;
107} 107}
108 108
109/* The form of the top of the frame on the stack */
110struct stack_frame {
111 struct stack_frame *next_frame;
112 unsigned long return_address;
113};
114
109static inline unsigned long print_context_stack(struct thread_info *tinfo, 115static inline unsigned long print_context_stack(struct thread_info *tinfo,
110 unsigned long *stack, unsigned long ebp, 116 unsigned long *stack, unsigned long ebp,
111 struct stacktrace_ops *ops, void *data) 117 struct stacktrace_ops *ops, void *data)
112{ 118{
113 unsigned long addr;
114
115#ifdef CONFIG_FRAME_POINTER 119#ifdef CONFIG_FRAME_POINTER
116 while (valid_stack_ptr(tinfo, (void *)ebp)) { 120 struct stack_frame *frame = (struct stack_frame *)ebp;
117 unsigned long new_ebp; 121 while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) {
118 addr = *(unsigned long *)(ebp + 4); 122 struct stack_frame *next;
123 unsigned long addr;
124
125 addr = frame->return_address;
119 ops->address(data, addr); 126 ops->address(data, addr);
120 /* 127 /*
121 * break out of recursive entries (such as 128 * break out of recursive entries (such as
122 * end_of_stack_stop_unwind_function). Also, 129 * end_of_stack_stop_unwind_function). Also,
123 * we can never allow a frame pointer to 130 * we can never allow a frame pointer to
124 * move downwards! 131 * move downwards!
125 */ 132 */
126 new_ebp = *(unsigned long *)ebp; 133 next = frame->next_frame;
127 if (new_ebp <= ebp) 134 if (next <= frame)
128 break; 135 break;
129 ebp = new_ebp; 136 frame = next;
130 } 137 }
131#else 138#else
132 while (valid_stack_ptr(tinfo, stack)) { 139 while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) {
140 unsigned long addr;
141
133 addr = *stack++; 142 addr = *stack++;
134 if (__kernel_text_address(addr)) 143 if (__kernel_text_address(addr))
135 ops->address(data, addr); 144 ops->address(data, addr);