Linux-libre 5.7.3-gnu
[librecmc/linux-libre.git] / arch / x86 / kernel / dumpstack_32.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  Copyright (C) 1991, 1992  Linus Torvalds
4  *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
5  */
6 #include <linux/sched/debug.h>
7 #include <linux/kallsyms.h>
8 #include <linux/kprobes.h>
9 #include <linux/uaccess.h>
10 #include <linux/hardirq.h>
11 #include <linux/kdebug.h>
12 #include <linux/export.h>
13 #include <linux/ptrace.h>
14 #include <linux/kexec.h>
15 #include <linux/sysfs.h>
16 #include <linux/bug.h>
17 #include <linux/nmi.h>
18
19 #include <asm/stacktrace.h>
20
21 const char *stack_type_name(enum stack_type type)
22 {
23         if (type == STACK_TYPE_IRQ)
24                 return "IRQ";
25
26         if (type == STACK_TYPE_SOFTIRQ)
27                 return "SOFTIRQ";
28
29         if (type == STACK_TYPE_ENTRY)
30                 return "ENTRY_TRAMPOLINE";
31
32         if (type == STACK_TYPE_EXCEPTION)
33                 return "#DF";
34
35         return NULL;
36 }
37
38 static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info)
39 {
40         unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack_ptr);
41         unsigned long *end   = begin + (THREAD_SIZE / sizeof(long));
42
43         /*
44          * This is a software stack, so 'end' can be a valid stack pointer.
45          * It just means the stack is empty.
46          */
47         if (stack < begin || stack > end)
48                 return false;
49
50         info->type      = STACK_TYPE_IRQ;
51         info->begin     = begin;
52         info->end       = end;
53
54         /*
55          * See irq_32.c -- the next stack pointer is stored at the beginning of
56          * the stack.
57          */
58         info->next_sp   = (unsigned long *)*begin;
59
60         return true;
61 }
62
63 static bool in_softirq_stack(unsigned long *stack, struct stack_info *info)
64 {
65         unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack_ptr);
66         unsigned long *end   = begin + (THREAD_SIZE / sizeof(long));
67
68         /*
69          * This is a software stack, so 'end' can be a valid stack pointer.
70          * It just means the stack is empty.
71          */
72         if (stack < begin || stack > end)
73                 return false;
74
75         info->type      = STACK_TYPE_SOFTIRQ;
76         info->begin     = begin;
77         info->end       = end;
78
79         /*
80          * The next stack pointer is stored at the beginning of the stack.
81          * See irq_32.c.
82          */
83         info->next_sp   = (unsigned long *)*begin;
84
85         return true;
86 }
87
88 static bool in_doublefault_stack(unsigned long *stack, struct stack_info *info)
89 {
90 #ifdef CONFIG_DOUBLEFAULT
91         struct cpu_entry_area *cea = get_cpu_entry_area(raw_smp_processor_id());
92         struct doublefault_stack *ss = &cea->doublefault_stack;
93
94         void *begin = ss->stack;
95         void *end = begin + sizeof(ss->stack);
96
97         if ((void *)stack < begin || (void *)stack >= end)
98                 return false;
99
100         info->type      = STACK_TYPE_EXCEPTION;
101         info->begin     = begin;
102         info->end       = end;
103         info->next_sp   = (unsigned long *)this_cpu_read(cpu_tss_rw.x86_tss.sp);
104
105         return true;
106 #else
107         return false;
108 #endif
109 }
110
111
112 int get_stack_info(unsigned long *stack, struct task_struct *task,
113                    struct stack_info *info, unsigned long *visit_mask)
114 {
115         if (!stack)
116                 goto unknown;
117
118         task = task ? : current;
119
120         if (in_task_stack(stack, task, info))
121                 goto recursion_check;
122
123         if (task != current)
124                 goto unknown;
125
126         if (in_entry_stack(stack, info))
127                 goto recursion_check;
128
129         if (in_hardirq_stack(stack, info))
130                 goto recursion_check;
131
132         if (in_softirq_stack(stack, info))
133                 goto recursion_check;
134
135         if (in_doublefault_stack(stack, info))
136                 goto recursion_check;
137
138         goto unknown;
139
140 recursion_check:
141         /*
142          * Make sure we don't iterate through any given stack more than once.
143          * If it comes up a second time then there's something wrong going on:
144          * just break out and report an unknown stack type.
145          */
146         if (visit_mask) {
147                 if (*visit_mask & (1UL << info->type)) {
148                         printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type);
149                         goto unknown;
150                 }
151                 *visit_mask |= 1UL << info->type;
152         }
153
154         return 0;
155
156 unknown:
157         info->type = STACK_TYPE_UNKNOWN;
158         return -EINVAL;
159 }