diff options
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/traps.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 9864d195c408..4fdd162f0bef 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -225,12 +225,19 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) | |||
225 | { | 225 | { |
226 | struct ops_and_data *oad = (struct ops_and_data *)context; | 226 | struct ops_and_data *oad = (struct ops_and_data *)context; |
227 | int n = 0; | 227 | int n = 0; |
228 | unsigned long sp = UNW_SP(info); | ||
228 | 229 | ||
230 | if (arch_unw_user_mode(info)) | ||
231 | return -1; | ||
229 | while (unwind(info) == 0 && UNW_PC(info)) { | 232 | while (unwind(info) == 0 && UNW_PC(info)) { |
230 | n++; | 233 | n++; |
231 | oad->ops->address(oad->data, UNW_PC(info)); | 234 | oad->ops->address(oad->data, UNW_PC(info)); |
232 | if (arch_unw_user_mode(info)) | 235 | if (arch_unw_user_mode(info)) |
233 | break; | 236 | break; |
237 | if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) | ||
238 | && sp > UNW_SP(info)) | ||
239 | break; | ||
240 | sp = UNW_SP(info); | ||
234 | } | 241 | } |
235 | return n; | 242 | return n; |
236 | } | 243 | } |