s390/vdso: drop unnecessary cc-ldoption
[linux-2.6-microblaze.git] / arch / x86 / kernel / dumpstack_64.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 static char *exception_stack_names[N_EXCEPTION_STACKS] = {
22                 [ DOUBLEFAULT_STACK-1   ]       = "#DF",
23                 [ NMI_STACK-1           ]       = "NMI",
24                 [ DEBUG_STACK-1         ]       = "#DB",
25                 [ MCE_STACK-1           ]       = "#MC",
26 };
27
28 static unsigned long exception_stack_sizes[N_EXCEPTION_STACKS] = {
29         [0 ... N_EXCEPTION_STACKS - 1]          = EXCEPTION_STKSZ,
30         [DEBUG_STACK - 1]                       = DEBUG_STKSZ
31 };
32
33 const char *stack_type_name(enum stack_type type)
34 {
35         BUILD_BUG_ON(N_EXCEPTION_STACKS != 4);
36
37         if (type == STACK_TYPE_IRQ)
38                 return "IRQ";
39
40         if (type == STACK_TYPE_ENTRY) {
41                 /*
42                  * On 64-bit, we have a generic entry stack that we
43                  * use for all the kernel entry points, including
44                  * SYSENTER.
45                  */
46                 return "ENTRY_TRAMPOLINE";
47         }
48
49         if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST)
50                 return exception_stack_names[type - STACK_TYPE_EXCEPTION];
51
52         return NULL;
53 }
54
55 static bool in_exception_stack(unsigned long *stack, struct stack_info *info)
56 {
57         unsigned long *begin, *end;
58         struct pt_regs *regs;
59         unsigned k;
60
61         BUILD_BUG_ON(N_EXCEPTION_STACKS != 4);
62
63         for (k = 0; k < N_EXCEPTION_STACKS; k++) {
64                 end   = (unsigned long *)raw_cpu_ptr(&orig_ist)->ist[k];
65                 begin = end - (exception_stack_sizes[k] / sizeof(long));
66                 regs  = (struct pt_regs *)end - 1;
67
68                 if (stack <= begin || stack >= end)
69                         continue;
70
71                 info->type      = STACK_TYPE_EXCEPTION + k;
72                 info->begin     = begin;
73                 info->end       = end;
74                 info->next_sp   = (unsigned long *)regs->sp;
75
76                 return true;
77         }
78
79         return false;
80 }
81
82 static bool in_irq_stack(unsigned long *stack, struct stack_info *info)
83 {
84         unsigned long *end   = (unsigned long *)this_cpu_read(irq_stack_ptr);
85         unsigned long *begin = end - (IRQ_STACK_SIZE / sizeof(long));
86
87         /*
88          * This is a software stack, so 'end' can be a valid stack pointer.
89          * It just means the stack is empty.
90          */
91         if (stack <= begin || stack > end)
92                 return false;
93
94         info->type      = STACK_TYPE_IRQ;
95         info->begin     = begin;
96         info->end       = end;
97
98         /*
99          * The next stack pointer is the first thing pushed by the entry code
100          * after switching to the irq stack.
101          */
102         info->next_sp = (unsigned long *)*(end - 1);
103
104         return true;
105 }
106
107 int get_stack_info(unsigned long *stack, struct task_struct *task,
108                    struct stack_info *info, unsigned long *visit_mask)
109 {
110         if (!stack)
111                 goto unknown;
112
113         task = task ? : current;
114
115         if (in_task_stack(stack, task, info))
116                 goto recursion_check;
117
118         if (task != current)
119                 goto unknown;
120
121         if (in_exception_stack(stack, info))
122                 goto recursion_check;
123
124         if (in_irq_stack(stack, info))
125                 goto recursion_check;
126
127         if (in_entry_stack(stack, info))
128                 goto recursion_check;
129
130         goto unknown;
131
132 recursion_check:
133         /*
134          * Make sure we don't iterate through any given stack more than once.
135          * If it comes up a second time then there's something wrong going on:
136          * just break out and report an unknown stack type.
137          */
138         if (visit_mask) {
139                 if (*visit_mask & (1UL << info->type)) {
140                         printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type);
141                         goto unknown;
142                 }
143                 *visit_mask |= 1UL << info->type;
144         }
145
146         return 0;
147
148 unknown:
149         info->type = STACK_TYPE_UNKNOWN;
150         return -EINVAL;
151 }