summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/dumpstack_32.c22
-rw-r--r--arch/x86/kernel/dumpstack_64.c35
2 files changed, 38 insertions, 19 deletions
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 50076d4366c4..2d65cfa5e0b4 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -89,16 +89,32 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,
task = task ? : current;
if (in_task_stack(stack, task, info))
- return 0;
+ goto recursion_check;
if (task != current)
goto unknown;
if (in_hardirq_stack(stack, info))
- return 0;
+ goto recursion_check;
if (in_softirq_stack(stack, info))
- return 0;
+ goto recursion_check;
+
+ goto unknown;
+
+recursion_check:
+ /*
+ * Make sure we don't iterate through any given stack more than once.
+ * If it comes up a second time then there's something wrong going on:
+ * just break out and report an unknown stack type.
+ */
+ if (visit_mask) {
+ if (*visit_mask & (1UL << info->type))
+ goto unknown;
+ *visit_mask |= 1UL << info->type;
+ }
+
+ return 0;
unknown:
info->type = STACK_TYPE_UNKNOWN;
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 2e708afe146d..8cb6004a4dfd 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -47,8 +47,7 @@ void stack_type_str(enum stack_type type, const char **begin, const char **end)
}
}
-static bool in_exception_stack(unsigned long *stack, struct stack_info *info,
- unsigned long *visit_mask)
+static bool in_exception_stack(unsigned long *stack, struct stack_info *info)
{
unsigned long *begin, *end;
struct pt_regs *regs;
@@ -64,16 +63,6 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info,
if (stack < begin || stack >= end)
continue;
- /*
- * Make sure we don't iterate through an exception stack more
- * than once. If it comes up a second time then there's
- * something wrong going on - just break out and report an
- * unknown stack type.
- */
- if (*visit_mask & (1U << k))
- break;
- *visit_mask |= 1U << k;
-
info->type = STACK_TYPE_EXCEPTION + k;
info->begin = begin;
info->end = end;
@@ -119,16 +108,30 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,
task = task ? : current;
if (in_task_stack(stack, task, info))
- return 0;
+ goto recursion_check;
if (task != current)
goto unknown;
- if (in_exception_stack(stack, info, visit_mask))
- return 0;
+ if (in_exception_stack(stack, info))
+ goto recursion_check;
if (in_irq_stack(stack, info))
- return 0;
+ goto recursion_check;
+
+ goto unknown;
+
+recursion_check:
+ /*
+ * Make sure we don't iterate through any given stack more than once.
+ * If it comes up a second time then there's something wrong going on:
+ * just break out and report an unknown stack type.
+ */
+ if (visit_mask) {
+ if (*visit_mask & (1UL << info->type))
+ goto unknown;
+ *visit_mask |= 1UL << info->type;
+ }
return 0;