]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - arch/x86/kernel/dumpstack_32.c
selftests/x86: Add test_vdso to test getcpu()
[mirror_ubuntu-artful-kernel.git] / arch / x86 / kernel / dumpstack_32.c
CommitLineData
2bc5f927
AH
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 */
5#include <linux/kallsyms.h>
6#include <linux/kprobes.h>
7#include <linux/uaccess.h>
2bc5f927
AH
8#include <linux/hardirq.h>
9#include <linux/kdebug.h>
186f4360 10#include <linux/export.h>
2bc5f927
AH
11#include <linux/ptrace.h>
12#include <linux/kexec.h>
b8030906 13#include <linux/sysfs.h>
2bc5f927
AH
14#include <linux/bug.h>
15#include <linux/nmi.h>
16
17#include <asm/stacktrace.h>
18
cb76c939 19void stack_type_str(enum stack_type type, const char **begin, const char **end)
198d208d 20{
cb76c939
JP
21 switch (type) {
22 case STACK_TYPE_IRQ:
23 case STACK_TYPE_SOFTIRQ:
24 *begin = "IRQ";
25 *end = "EOI";
26 break;
27 default:
28 *begin = NULL;
29 *end = NULL;
30 }
198d208d
SR
31}
32
cb76c939
JP
33static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info)
34{
35 unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack);
36 unsigned long *end = begin + (THREAD_SIZE / sizeof(long));
37
5fe599e0
JP
38 /*
39 * This is a software stack, so 'end' can be a valid stack pointer.
40 * It just means the stack is empty.
41 */
42 if (stack < begin || stack > end)
cb76c939
JP
43 return false;
44
45 info->type = STACK_TYPE_IRQ;
46 info->begin = begin;
47 info->end = end;
48
49 /*
50 * See irq_32.c -- the next stack pointer is stored at the beginning of
51 * the stack.
52 */
53 info->next_sp = (unsigned long *)*begin;
198d208d 54
cb76c939
JP
55 return true;
56}
57
58static bool in_softirq_stack(unsigned long *stack, struct stack_info *info)
198d208d 59{
cb76c939
JP
60 unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack);
61 unsigned long *end = begin + (THREAD_SIZE / sizeof(long));
62
5fe599e0
JP
63 /*
64 * This is a software stack, so 'end' can be a valid stack pointer.
65 * It just means the stack is empty.
66 */
67 if (stack < begin || stack > end)
cb76c939
JP
68 return false;
69
70 info->type = STACK_TYPE_SOFTIRQ;
71 info->begin = begin;
72 info->end = end;
73
74 /*
75 * The next stack pointer is stored at the beginning of the stack.
76 * See irq_32.c.
77 */
78 info->next_sp = (unsigned long *)*begin;
198d208d 79
cb76c939 80 return true;
198d208d
SR
81}
82
cb76c939
JP
83int get_stack_info(unsigned long *stack, struct task_struct *task,
84 struct stack_info *info, unsigned long *visit_mask)
198d208d 85{
cb76c939
JP
86 if (!stack)
87 goto unknown;
198d208d 88
cb76c939
JP
89 task = task ? : current;
90
91 if (in_task_stack(stack, task, info))
fcd709ef 92 goto recursion_check;
cb76c939
JP
93
94 if (task != current)
95 goto unknown;
96
97 if (in_hardirq_stack(stack, info))
fcd709ef 98 goto recursion_check;
cb76c939
JP
99
100 if (in_softirq_stack(stack, info))
fcd709ef
JP
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) {
0d2b8579
JP
112 if (*visit_mask & (1UL << info->type)) {
113 printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type);
fcd709ef 114 goto unknown;
0d2b8579 115 }
fcd709ef
JP
116 *visit_mask |= 1UL << info->type;
117 }
118
119 return 0;
cb76c939
JP
120
121unknown:
122 info->type = STACK_TYPE_UNKNOWN;
123 return -EINVAL;
198d208d 124}
0406ca6d 125
57da8b96 126void show_regs(struct pt_regs *regs)
2bc5f927
AH
127{
128 int i;
129
a43cb95d 130 show_regs_print_info(KERN_EMERG);
f39b6f0e 131 __show_regs(regs, !user_mode(regs));
2bc5f927 132
2bc5f927
AH
133 /*
134 * When in-kernel, we also print out the stack and code at the
135 * time of the fault..
136 */
f39b6f0e 137 if (!user_mode(regs)) {
2bc5f927
AH
138 unsigned int code_prologue = code_bytes * 43 / 64;
139 unsigned int code_len = code_bytes;
140 unsigned char c;
141 u8 *ip;
142
0ee1dd9f 143 show_trace_log_lvl(current, regs, NULL, KERN_EMERG);
2bc5f927 144
c767a54b 145 pr_emerg("Code:");
2bc5f927
AH
146
147 ip = (u8 *)regs->ip - code_prologue;
148 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
8a541665 149 /* try starting at IP */
2bc5f927
AH
150 ip = (u8 *)regs->ip;
151 code_len = code_len - code_prologue + 1;
152 }
153 for (i = 0; i < code_len; i++, ip++) {
154 if (ip < (u8 *)PAGE_OFFSET ||
155 probe_kernel_address(ip, c)) {
c767a54b 156 pr_cont(" Bad EIP value.");
2bc5f927
AH
157 break;
158 }
159 if (ip == (u8 *)regs->ip)
c767a54b 160 pr_cont(" <%02x>", c);
2bc5f927 161 else
c767a54b 162 pr_cont(" %02x", c);
2bc5f927
AH
163 }
164 }
c767a54b 165 pr_cont("\n");
2bc5f927
AH
166}
167
168int is_valid_bugaddr(unsigned long ip)
169{
170 unsigned short ud2;
171
172 if (ip < PAGE_OFFSET)
173 return 0;
174 if (probe_kernel_address((unsigned short *)ip, ud2))
175 return 0;
176
177 return ud2 == 0x0b0f;
178}