aboutsummaryrefslogtreecommitdiffstats
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,
89 task = task ? : current; 89 task = task ? : current;
90 90
91 if (in_task_stack(stack, task, info)) 91 if (in_task_stack(stack, task, info))
92 return 0; 92 goto recursion_check;
93 93
94 if (task != current) 94 if (task != current)
95 goto unknown; 95 goto unknown;
96 96
97 if (in_hardirq_stack(stack, info)) 97 if (in_hardirq_stack(stack, info))
98 return 0; 98 goto recursion_check;
99 99
100 if (in_softirq_stack(stack, info)) 100 if (in_softirq_stack(stack, info))
101 return 0; 101 goto recursion_check;
102
103 goto unknown;
104
105recursion_check:
106 /*
107 * Make sure we don't iterate through any given stack more than once.
108 * If it comes up a second time then there's something wrong going on:
109 * just break out and report an unknown stack type.
110 */
111 if (visit_mask) {
112 if (*visit_mask & (1UL << info->type))
113 goto unknown;
114 *visit_mask |= 1UL << info->type;
115 }
116
117 return 0;
102 118
103unknown: 119unknown:
104 info->type = STACK_TYPE_UNKNOWN; 120 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)
47 } 47 }
48} 48}
49 49
50static bool in_exception_stack(unsigned long *stack, struct stack_info *info, 50static bool in_exception_stack(unsigned long *stack, struct stack_info *info)
51 unsigned long *visit_mask)
52{ 51{
53 unsigned long *begin, *end; 52 unsigned long *begin, *end;
54 struct pt_regs *regs; 53 struct pt_regs *regs;
@@ -64,16 +63,6 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info,
64 if (stack < begin || stack >= end) 63 if (stack < begin || stack >= end)
65 continue; 64 continue;
66 65
67 /*
68 * Make sure we don't iterate through an exception stack more
69 * than once. If it comes up a second time then there's
70 * something wrong going on - just break out and report an
71 * unknown stack type.
72 */
73 if (*visit_mask & (1U << k))
74 break;
75 *visit_mask |= 1U << k;
76
77 info->type = STACK_TYPE_EXCEPTION + k; 66 info->type = STACK_TYPE_EXCEPTION + k;
78 info->begin = begin; 67 info->begin = begin;
79 info->end = end; 68 info->end = end;
@@ -119,16 +108,30 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,
119 task = task ? : current; 108 task = task ? : current;
120 109
121 if (in_task_stack(stack, task, info)) 110 if (in_task_stack(stack, task, info))
122 return 0; 111 goto recursion_check;
123 112
124 if (task != current) 113 if (task != current)
125 goto unknown; 114 goto unknown;
126 115
127 if (in_exception_stack(stack, info, visit_mask)) 116 if (in_exception_stack(stack, info))
128 return 0; 117 goto recursion_check;
129 118
130 if (in_irq_stack(stack, info)) 119 if (in_irq_stack(stack, info))
131 return 0; 120 goto recursion_check;
121
122 goto unknown;
123
124recursion_check:
125 /*
126 * Make sure we don't iterate through any given stack more than once.
127 * If it comes up a second time then there's something wrong going on:
128 * just break out and report an unknown stack type.
129 */
130 if (visit_mask) {
131 if (*visit_mask & (1UL << info->type))
132 goto unknown;
133 *visit_mask |= 1UL << info->type;
134 }
132 135
133 return 0; 136 return 0;
134 137