diff options
-rw-r--r-- | arch/x86/kernel/dumpstack_32.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack_64.c | 35 |
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 | |||
105 | recursion_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 | ||
103 | unknown: | 119 | unknown: |
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 | ||
50 | static bool in_exception_stack(unsigned long *stack, struct stack_info *info, | 50 | static 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 | |||
124 | recursion_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 | ||