Commit 7aa89746e89fca8fc722485aaf4454f2b636cf4d
Committed by
Linus Torvalds
1 parent
ce63ad78b5
Exists in
master
and in
7 other branches
[PATCH] i386: fix stack dump loglevel
Recent changes caused part of stack traces from SysRq-T to print at KERN_EMERG loglevel. Also, parts of stack dump during oops were failing to print at that level when they should. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 1 changed file with 39 additions and 18 deletions Inline Diff
arch/i386/kernel/traps.c
1 | /* | 1 | /* |
2 | * linux/arch/i386/traps.c | 2 | * linux/arch/i386/traps.c |
3 | * | 3 | * |
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 4 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * | 5 | * |
6 | * Pentium III FXSR, SSE support | 6 | * Pentium III FXSR, SSE support |
7 | * Gareth Hughes <gareth@valinux.com>, May 2000 | 7 | * Gareth Hughes <gareth@valinux.com>, May 2000 |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * 'Traps.c' handles hardware traps and faults after we have saved some | 11 | * 'Traps.c' handles hardware traps and faults after we have saved some |
12 | * state in 'asm.s'. | 12 | * state in 'asm.s'. |
13 | */ | 13 | */ |
14 | #include <linux/config.h> | 14 | #include <linux/config.h> |
15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/highmem.h> | 25 | #include <linux/highmem.h> |
26 | #include <linux/kallsyms.h> | 26 | #include <linux/kallsyms.h> |
27 | #include <linux/ptrace.h> | 27 | #include <linux/ptrace.h> |
28 | #include <linux/utsname.h> | 28 | #include <linux/utsname.h> |
29 | #include <linux/kprobes.h> | 29 | #include <linux/kprobes.h> |
30 | #include <linux/kexec.h> | 30 | #include <linux/kexec.h> |
31 | 31 | ||
32 | #ifdef CONFIG_EISA | 32 | #ifdef CONFIG_EISA |
33 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
34 | #include <linux/eisa.h> | 34 | #include <linux/eisa.h> |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #ifdef CONFIG_MCA | 37 | #ifdef CONFIG_MCA |
38 | #include <linux/mca.h> | 38 | #include <linux/mca.h> |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #include <asm/processor.h> | 41 | #include <asm/processor.h> |
42 | #include <asm/system.h> | 42 | #include <asm/system.h> |
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | #include <asm/io.h> | 44 | #include <asm/io.h> |
45 | #include <asm/atomic.h> | 45 | #include <asm/atomic.h> |
46 | #include <asm/debugreg.h> | 46 | #include <asm/debugreg.h> |
47 | #include <asm/desc.h> | 47 | #include <asm/desc.h> |
48 | #include <asm/i387.h> | 48 | #include <asm/i387.h> |
49 | #include <asm/nmi.h> | 49 | #include <asm/nmi.h> |
50 | 50 | ||
51 | #include <asm/smp.h> | 51 | #include <asm/smp.h> |
52 | #include <asm/arch_hooks.h> | 52 | #include <asm/arch_hooks.h> |
53 | #include <asm/kdebug.h> | 53 | #include <asm/kdebug.h> |
54 | 54 | ||
55 | #include <linux/module.h> | 55 | #include <linux/module.h> |
56 | 56 | ||
57 | #include "mach_traps.h" | 57 | #include "mach_traps.h" |
58 | 58 | ||
59 | asmlinkage int system_call(void); | 59 | asmlinkage int system_call(void); |
60 | 60 | ||
61 | struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, | 61 | struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, |
62 | { 0, 0 }, { 0, 0 } }; | 62 | { 0, 0 }, { 0, 0 } }; |
63 | 63 | ||
64 | /* Do we ignore FPU interrupts ? */ | 64 | /* Do we ignore FPU interrupts ? */ |
65 | char ignore_fpu_irq = 0; | 65 | char ignore_fpu_irq = 0; |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * The IDT has to be page-aligned to simplify the Pentium | 68 | * The IDT has to be page-aligned to simplify the Pentium |
69 | * F0 0F bug workaround.. We have a special link segment | 69 | * F0 0F bug workaround.. We have a special link segment |
70 | * for this. | 70 | * for this. |
71 | */ | 71 | */ |
72 | struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; | 72 | struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; |
73 | 73 | ||
74 | asmlinkage void divide_error(void); | 74 | asmlinkage void divide_error(void); |
75 | asmlinkage void debug(void); | 75 | asmlinkage void debug(void); |
76 | asmlinkage void nmi(void); | 76 | asmlinkage void nmi(void); |
77 | asmlinkage void int3(void); | 77 | asmlinkage void int3(void); |
78 | asmlinkage void overflow(void); | 78 | asmlinkage void overflow(void); |
79 | asmlinkage void bounds(void); | 79 | asmlinkage void bounds(void); |
80 | asmlinkage void invalid_op(void); | 80 | asmlinkage void invalid_op(void); |
81 | asmlinkage void device_not_available(void); | 81 | asmlinkage void device_not_available(void); |
82 | asmlinkage void coprocessor_segment_overrun(void); | 82 | asmlinkage void coprocessor_segment_overrun(void); |
83 | asmlinkage void invalid_TSS(void); | 83 | asmlinkage void invalid_TSS(void); |
84 | asmlinkage void segment_not_present(void); | 84 | asmlinkage void segment_not_present(void); |
85 | asmlinkage void stack_segment(void); | 85 | asmlinkage void stack_segment(void); |
86 | asmlinkage void general_protection(void); | 86 | asmlinkage void general_protection(void); |
87 | asmlinkage void page_fault(void); | 87 | asmlinkage void page_fault(void); |
88 | asmlinkage void coprocessor_error(void); | 88 | asmlinkage void coprocessor_error(void); |
89 | asmlinkage void simd_coprocessor_error(void); | 89 | asmlinkage void simd_coprocessor_error(void); |
90 | asmlinkage void alignment_check(void); | 90 | asmlinkage void alignment_check(void); |
91 | asmlinkage void spurious_interrupt_bug(void); | 91 | asmlinkage void spurious_interrupt_bug(void); |
92 | asmlinkage void machine_check(void); | 92 | asmlinkage void machine_check(void); |
93 | 93 | ||
94 | static int kstack_depth_to_print = 24; | 94 | static int kstack_depth_to_print = 24; |
95 | struct notifier_block *i386die_chain; | 95 | struct notifier_block *i386die_chain; |
96 | static DEFINE_SPINLOCK(die_notifier_lock); | 96 | static DEFINE_SPINLOCK(die_notifier_lock); |
97 | 97 | ||
98 | int register_die_notifier(struct notifier_block *nb) | 98 | int register_die_notifier(struct notifier_block *nb) |
99 | { | 99 | { |
100 | int err = 0; | 100 | int err = 0; |
101 | unsigned long flags; | 101 | unsigned long flags; |
102 | spin_lock_irqsave(&die_notifier_lock, flags); | 102 | spin_lock_irqsave(&die_notifier_lock, flags); |
103 | err = notifier_chain_register(&i386die_chain, nb); | 103 | err = notifier_chain_register(&i386die_chain, nb); |
104 | spin_unlock_irqrestore(&die_notifier_lock, flags); | 104 | spin_unlock_irqrestore(&die_notifier_lock, flags); |
105 | return err; | 105 | return err; |
106 | } | 106 | } |
107 | EXPORT_SYMBOL(register_die_notifier); | 107 | EXPORT_SYMBOL(register_die_notifier); |
108 | 108 | ||
109 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | 109 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) |
110 | { | 110 | { |
111 | return p > (void *)tinfo && | 111 | return p > (void *)tinfo && |
112 | p < (void *)tinfo + THREAD_SIZE - 3; | 112 | p < (void *)tinfo + THREAD_SIZE - 3; |
113 | } | 113 | } |
114 | 114 | ||
115 | static void print_addr_and_symbol(unsigned long addr, char *log_lvl) | ||
116 | { | ||
117 | printk(log_lvl); | ||
118 | printk(" [<%08lx>] ", addr); | ||
119 | print_symbol("%s", addr); | ||
120 | printk("\n"); | ||
121 | } | ||
122 | |||
115 | static inline unsigned long print_context_stack(struct thread_info *tinfo, | 123 | static inline unsigned long print_context_stack(struct thread_info *tinfo, |
116 | unsigned long *stack, unsigned long ebp) | 124 | unsigned long *stack, unsigned long ebp, |
125 | char *log_lvl) | ||
117 | { | 126 | { |
118 | unsigned long addr; | 127 | unsigned long addr; |
119 | 128 | ||
120 | #ifdef CONFIG_FRAME_POINTER | 129 | #ifdef CONFIG_FRAME_POINTER |
121 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | 130 | while (valid_stack_ptr(tinfo, (void *)ebp)) { |
122 | addr = *(unsigned long *)(ebp + 4); | 131 | addr = *(unsigned long *)(ebp + 4); |
123 | printk(KERN_EMERG " [<%08lx>] ", addr); | 132 | print_addr_and_symbol(addr, log_lvl); |
124 | print_symbol("%s", addr); | ||
125 | printk("\n"); | ||
126 | ebp = *(unsigned long *)ebp; | 133 | ebp = *(unsigned long *)ebp; |
127 | } | 134 | } |
128 | #else | 135 | #else |
129 | while (valid_stack_ptr(tinfo, stack)) { | 136 | while (valid_stack_ptr(tinfo, stack)) { |
130 | addr = *stack++; | 137 | addr = *stack++; |
131 | if (__kernel_text_address(addr)) { | 138 | if (__kernel_text_address(addr)) |
132 | printk(KERN_EMERG " [<%08lx>]", addr); | 139 | print_addr_and_symbol(addr, log_lvl); |
133 | print_symbol(" %s", addr); | ||
134 | printk("\n"); | ||
135 | } | ||
136 | } | 140 | } |
137 | #endif | 141 | #endif |
138 | return ebp; | 142 | return ebp; |
139 | } | 143 | } |
140 | 144 | ||
141 | void show_trace(struct task_struct *task, unsigned long * stack) | 145 | static void show_trace_log_lvl(struct task_struct *task, |
146 | unsigned long *stack, char *log_lvl) | ||
142 | { | 147 | { |
143 | unsigned long ebp; | 148 | unsigned long ebp; |
144 | 149 | ||
145 | if (!task) | 150 | if (!task) |
146 | task = current; | 151 | task = current; |
147 | 152 | ||
148 | if (task == current) { | 153 | if (task == current) { |
149 | /* Grab ebp right from our regs */ | 154 | /* Grab ebp right from our regs */ |
150 | asm ("movl %%ebp, %0" : "=r" (ebp) : ); | 155 | asm ("movl %%ebp, %0" : "=r" (ebp) : ); |
151 | } else { | 156 | } else { |
152 | /* ebp is the last reg pushed by switch_to */ | 157 | /* ebp is the last reg pushed by switch_to */ |
153 | ebp = *(unsigned long *) task->thread.esp; | 158 | ebp = *(unsigned long *) task->thread.esp; |
154 | } | 159 | } |
155 | 160 | ||
156 | while (1) { | 161 | while (1) { |
157 | struct thread_info *context; | 162 | struct thread_info *context; |
158 | context = (struct thread_info *) | 163 | context = (struct thread_info *) |
159 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | 164 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); |
160 | ebp = print_context_stack(context, stack, ebp); | 165 | ebp = print_context_stack(context, stack, ebp, log_lvl); |
161 | stack = (unsigned long*)context->previous_esp; | 166 | stack = (unsigned long*)context->previous_esp; |
162 | if (!stack) | 167 | if (!stack) |
163 | break; | 168 | break; |
164 | printk(KERN_EMERG " =======================\n"); | 169 | printk(KERN_EMERG " =======================\n"); |
165 | } | 170 | } |
166 | } | 171 | } |
167 | 172 | ||
168 | void show_stack(struct task_struct *task, unsigned long *esp) | 173 | void show_trace(struct task_struct *task, unsigned long * stack) |
169 | { | 174 | { |
175 | show_trace_log_lvl(task, stack, ""); | ||
176 | } | ||
177 | |||
178 | static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp, | ||
179 | char *log_lvl) | ||
180 | { | ||
170 | unsigned long *stack; | 181 | unsigned long *stack; |
171 | int i; | 182 | int i; |
172 | 183 | ||
173 | if (esp == NULL) { | 184 | if (esp == NULL) { |
174 | if (task) | 185 | if (task) |
175 | esp = (unsigned long*)task->thread.esp; | 186 | esp = (unsigned long*)task->thread.esp; |
176 | else | 187 | else |
177 | esp = (unsigned long *)&esp; | 188 | esp = (unsigned long *)&esp; |
178 | } | 189 | } |
179 | 190 | ||
180 | stack = esp; | 191 | stack = esp; |
181 | printk(KERN_EMERG); | 192 | printk(log_lvl); |
182 | for(i = 0; i < kstack_depth_to_print; i++) { | 193 | for(i = 0; i < kstack_depth_to_print; i++) { |
183 | if (kstack_end(stack)) | 194 | if (kstack_end(stack)) |
184 | break; | 195 | break; |
185 | if (i && ((i % 8) == 0)) | 196 | if (i && ((i % 8) == 0)) { |
186 | printk("\n" KERN_EMERG " "); | 197 | printk("\n"); |
198 | printk(log_lvl); | ||
199 | printk(" "); | ||
200 | } | ||
187 | printk("%08lx ", *stack++); | 201 | printk("%08lx ", *stack++); |
188 | } | 202 | } |
189 | printk("\n" KERN_EMERG "Call Trace:\n"); | 203 | printk("\n"); |
190 | show_trace(task, esp); | 204 | printk(log_lvl); |
205 | printk("Call Trace:\n"); | ||
206 | show_trace_log_lvl(task, esp, log_lvl); | ||
191 | } | 207 | } |
192 | 208 | ||
209 | void show_stack(struct task_struct *task, unsigned long *esp) | ||
210 | { | ||
211 | show_stack_log_lvl(task, esp, ""); | ||
212 | } | ||
213 | |||
193 | /* | 214 | /* |
194 | * The architecture-independent dump_stack generator | 215 | * The architecture-independent dump_stack generator |
195 | */ | 216 | */ |
196 | void dump_stack(void) | 217 | void dump_stack(void) |
197 | { | 218 | { |
198 | unsigned long stack; | 219 | unsigned long stack; |
199 | 220 | ||
200 | show_trace(current, &stack); | 221 | show_trace(current, &stack); |
201 | } | 222 | } |
202 | 223 | ||
203 | EXPORT_SYMBOL(dump_stack); | 224 | EXPORT_SYMBOL(dump_stack); |
204 | 225 | ||
205 | void show_registers(struct pt_regs *regs) | 226 | void show_registers(struct pt_regs *regs) |
206 | { | 227 | { |
207 | int i; | 228 | int i; |
208 | int in_kernel = 1; | 229 | int in_kernel = 1; |
209 | unsigned long esp; | 230 | unsigned long esp; |
210 | unsigned short ss; | 231 | unsigned short ss; |
211 | 232 | ||
212 | esp = (unsigned long) (®s->esp); | 233 | esp = (unsigned long) (®s->esp); |
213 | savesegment(ss, ss); | 234 | savesegment(ss, ss); |
214 | if (user_mode(regs)) { | 235 | if (user_mode(regs)) { |
215 | in_kernel = 0; | 236 | in_kernel = 0; |
216 | esp = regs->esp; | 237 | esp = regs->esp; |
217 | ss = regs->xss & 0xffff; | 238 | ss = regs->xss & 0xffff; |
218 | } | 239 | } |
219 | print_modules(); | 240 | print_modules(); |
220 | printk(KERN_EMERG "CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\n" | 241 | printk(KERN_EMERG "CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\n" |
221 | "EFLAGS: %08lx (%s) \n", | 242 | "EFLAGS: %08lx (%s) \n", |
222 | smp_processor_id(), 0xffff & regs->xcs, regs->eip, | 243 | smp_processor_id(), 0xffff & regs->xcs, regs->eip, |
223 | print_tainted(), regs->eflags, system_utsname.release); | 244 | print_tainted(), regs->eflags, system_utsname.release); |
224 | print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip); | 245 | print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip); |
225 | printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", | 246 | printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", |
226 | regs->eax, regs->ebx, regs->ecx, regs->edx); | 247 | regs->eax, regs->ebx, regs->ecx, regs->edx); |
227 | printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", | 248 | printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", |
228 | regs->esi, regs->edi, regs->ebp, esp); | 249 | regs->esi, regs->edi, regs->ebp, esp); |
229 | printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n", | 250 | printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n", |
230 | regs->xds & 0xffff, regs->xes & 0xffff, ss); | 251 | regs->xds & 0xffff, regs->xes & 0xffff, ss); |
231 | printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)", | 252 | printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)", |
232 | current->comm, current->pid, current_thread_info(), current); | 253 | current->comm, current->pid, current_thread_info(), current); |
233 | /* | 254 | /* |
234 | * When in-kernel, we also print out the stack and code at the | 255 | * When in-kernel, we also print out the stack and code at the |
235 | * time of the fault.. | 256 | * time of the fault.. |
236 | */ | 257 | */ |
237 | if (in_kernel) { | 258 | if (in_kernel) { |
238 | u8 __user *eip; | 259 | u8 __user *eip; |
239 | 260 | ||
240 | printk("\n" KERN_EMERG "Stack: "); | 261 | printk("\n" KERN_EMERG "Stack: "); |
241 | show_stack(NULL, (unsigned long*)esp); | 262 | show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG); |
242 | 263 | ||
243 | printk(KERN_EMERG "Code: "); | 264 | printk(KERN_EMERG "Code: "); |
244 | 265 | ||
245 | eip = (u8 __user *)regs->eip - 43; | 266 | eip = (u8 __user *)regs->eip - 43; |
246 | for (i = 0; i < 64; i++, eip++) { | 267 | for (i = 0; i < 64; i++, eip++) { |
247 | unsigned char c; | 268 | unsigned char c; |
248 | 269 | ||
249 | if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { | 270 | if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { |
250 | printk(" Bad EIP value."); | 271 | printk(" Bad EIP value."); |
251 | break; | 272 | break; |
252 | } | 273 | } |
253 | if (eip == (u8 __user *)regs->eip) | 274 | if (eip == (u8 __user *)regs->eip) |
254 | printk("<%02x> ", c); | 275 | printk("<%02x> ", c); |
255 | else | 276 | else |
256 | printk("%02x ", c); | 277 | printk("%02x ", c); |
257 | } | 278 | } |
258 | } | 279 | } |
259 | printk("\n"); | 280 | printk("\n"); |
260 | } | 281 | } |
261 | 282 | ||
262 | static void handle_BUG(struct pt_regs *regs) | 283 | static void handle_BUG(struct pt_regs *regs) |
263 | { | 284 | { |
264 | unsigned short ud2; | 285 | unsigned short ud2; |
265 | unsigned short line; | 286 | unsigned short line; |
266 | char *file; | 287 | char *file; |
267 | char c; | 288 | char c; |
268 | unsigned long eip; | 289 | unsigned long eip; |
269 | 290 | ||
270 | eip = regs->eip; | 291 | eip = regs->eip; |
271 | 292 | ||
272 | if (eip < PAGE_OFFSET) | 293 | if (eip < PAGE_OFFSET) |
273 | goto no_bug; | 294 | goto no_bug; |
274 | if (__get_user(ud2, (unsigned short __user *)eip)) | 295 | if (__get_user(ud2, (unsigned short __user *)eip)) |
275 | goto no_bug; | 296 | goto no_bug; |
276 | if (ud2 != 0x0b0f) | 297 | if (ud2 != 0x0b0f) |
277 | goto no_bug; | 298 | goto no_bug; |
278 | if (__get_user(line, (unsigned short __user *)(eip + 2))) | 299 | if (__get_user(line, (unsigned short __user *)(eip + 2))) |
279 | goto bug; | 300 | goto bug; |
280 | if (__get_user(file, (char * __user *)(eip + 4)) || | 301 | if (__get_user(file, (char * __user *)(eip + 4)) || |
281 | (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) | 302 | (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) |
282 | file = "<bad filename>"; | 303 | file = "<bad filename>"; |
283 | 304 | ||
284 | printk(KERN_EMERG "------------[ cut here ]------------\n"); | 305 | printk(KERN_EMERG "------------[ cut here ]------------\n"); |
285 | printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); | 306 | printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); |
286 | 307 | ||
287 | no_bug: | 308 | no_bug: |
288 | return; | 309 | return; |
289 | 310 | ||
290 | /* Here we know it was a BUG but file-n-line is unavailable */ | 311 | /* Here we know it was a BUG but file-n-line is unavailable */ |
291 | bug: | 312 | bug: |
292 | printk(KERN_EMERG "Kernel BUG\n"); | 313 | printk(KERN_EMERG "Kernel BUG\n"); |
293 | } | 314 | } |
294 | 315 | ||
295 | /* This is gone through when something in the kernel | 316 | /* This is gone through when something in the kernel |
296 | * has done something bad and is about to be terminated. | 317 | * has done something bad and is about to be terminated. |
297 | */ | 318 | */ |
298 | void die(const char * str, struct pt_regs * regs, long err) | 319 | void die(const char * str, struct pt_regs * regs, long err) |
299 | { | 320 | { |
300 | static struct { | 321 | static struct { |
301 | spinlock_t lock; | 322 | spinlock_t lock; |
302 | u32 lock_owner; | 323 | u32 lock_owner; |
303 | int lock_owner_depth; | 324 | int lock_owner_depth; |
304 | } die = { | 325 | } die = { |
305 | .lock = SPIN_LOCK_UNLOCKED, | 326 | .lock = SPIN_LOCK_UNLOCKED, |
306 | .lock_owner = -1, | 327 | .lock_owner = -1, |
307 | .lock_owner_depth = 0 | 328 | .lock_owner_depth = 0 |
308 | }; | 329 | }; |
309 | static int die_counter; | 330 | static int die_counter; |
310 | unsigned long flags; | 331 | unsigned long flags; |
311 | 332 | ||
312 | if (die.lock_owner != raw_smp_processor_id()) { | 333 | if (die.lock_owner != raw_smp_processor_id()) { |
313 | console_verbose(); | 334 | console_verbose(); |
314 | spin_lock_irqsave(&die.lock, flags); | 335 | spin_lock_irqsave(&die.lock, flags); |
315 | die.lock_owner = smp_processor_id(); | 336 | die.lock_owner = smp_processor_id(); |
316 | die.lock_owner_depth = 0; | 337 | die.lock_owner_depth = 0; |
317 | bust_spinlocks(1); | 338 | bust_spinlocks(1); |
318 | } | 339 | } |
319 | else | 340 | else |
320 | local_save_flags(flags); | 341 | local_save_flags(flags); |
321 | 342 | ||
322 | if (++die.lock_owner_depth < 3) { | 343 | if (++die.lock_owner_depth < 3) { |
323 | int nl = 0; | 344 | int nl = 0; |
324 | handle_BUG(regs); | 345 | handle_BUG(regs); |
325 | printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); | 346 | printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); |
326 | #ifdef CONFIG_PREEMPT | 347 | #ifdef CONFIG_PREEMPT |
327 | printk(KERN_EMERG "PREEMPT "); | 348 | printk(KERN_EMERG "PREEMPT "); |
328 | nl = 1; | 349 | nl = 1; |
329 | #endif | 350 | #endif |
330 | #ifdef CONFIG_SMP | 351 | #ifdef CONFIG_SMP |
331 | if (!nl) | 352 | if (!nl) |
332 | printk(KERN_EMERG); | 353 | printk(KERN_EMERG); |
333 | printk("SMP "); | 354 | printk("SMP "); |
334 | nl = 1; | 355 | nl = 1; |
335 | #endif | 356 | #endif |
336 | #ifdef CONFIG_DEBUG_PAGEALLOC | 357 | #ifdef CONFIG_DEBUG_PAGEALLOC |
337 | if (!nl) | 358 | if (!nl) |
338 | printk(KERN_EMERG); | 359 | printk(KERN_EMERG); |
339 | printk("DEBUG_PAGEALLOC"); | 360 | printk("DEBUG_PAGEALLOC"); |
340 | nl = 1; | 361 | nl = 1; |
341 | #endif | 362 | #endif |
342 | if (nl) | 363 | if (nl) |
343 | printk("\n"); | 364 | printk("\n"); |
344 | notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); | 365 | notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); |
345 | show_registers(regs); | 366 | show_registers(regs); |
346 | } else | 367 | } else |
347 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); | 368 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); |
348 | 369 | ||
349 | bust_spinlocks(0); | 370 | bust_spinlocks(0); |
350 | die.lock_owner = -1; | 371 | die.lock_owner = -1; |
351 | spin_unlock_irqrestore(&die.lock, flags); | 372 | spin_unlock_irqrestore(&die.lock, flags); |
352 | 373 | ||
353 | if (kexec_should_crash(current)) | 374 | if (kexec_should_crash(current)) |
354 | crash_kexec(regs); | 375 | crash_kexec(regs); |
355 | 376 | ||
356 | if (in_interrupt()) | 377 | if (in_interrupt()) |
357 | panic("Fatal exception in interrupt"); | 378 | panic("Fatal exception in interrupt"); |
358 | 379 | ||
359 | if (panic_on_oops) { | 380 | if (panic_on_oops) { |
360 | printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); | 381 | printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); |
361 | ssleep(5); | 382 | ssleep(5); |
362 | panic("Fatal exception"); | 383 | panic("Fatal exception"); |
363 | } | 384 | } |
364 | do_exit(SIGSEGV); | 385 | do_exit(SIGSEGV); |
365 | } | 386 | } |
366 | 387 | ||
367 | static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) | 388 | static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) |
368 | { | 389 | { |
369 | if (!user_mode_vm(regs)) | 390 | if (!user_mode_vm(regs)) |
370 | die(str, regs, err); | 391 | die(str, regs, err); |
371 | } | 392 | } |
372 | 393 | ||
373 | static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, | 394 | static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, |
374 | struct pt_regs * regs, long error_code, | 395 | struct pt_regs * regs, long error_code, |
375 | siginfo_t *info) | 396 | siginfo_t *info) |
376 | { | 397 | { |
377 | struct task_struct *tsk = current; | 398 | struct task_struct *tsk = current; |
378 | tsk->thread.error_code = error_code; | 399 | tsk->thread.error_code = error_code; |
379 | tsk->thread.trap_no = trapnr; | 400 | tsk->thread.trap_no = trapnr; |
380 | 401 | ||
381 | if (regs->eflags & VM_MASK) { | 402 | if (regs->eflags & VM_MASK) { |
382 | if (vm86) | 403 | if (vm86) |
383 | goto vm86_trap; | 404 | goto vm86_trap; |
384 | goto trap_signal; | 405 | goto trap_signal; |
385 | } | 406 | } |
386 | 407 | ||
387 | if (!user_mode(regs)) | 408 | if (!user_mode(regs)) |
388 | goto kernel_trap; | 409 | goto kernel_trap; |
389 | 410 | ||
390 | trap_signal: { | 411 | trap_signal: { |
391 | if (info) | 412 | if (info) |
392 | force_sig_info(signr, info, tsk); | 413 | force_sig_info(signr, info, tsk); |
393 | else | 414 | else |
394 | force_sig(signr, tsk); | 415 | force_sig(signr, tsk); |
395 | return; | 416 | return; |
396 | } | 417 | } |
397 | 418 | ||
398 | kernel_trap: { | 419 | kernel_trap: { |
399 | if (!fixup_exception(regs)) | 420 | if (!fixup_exception(regs)) |
400 | die(str, regs, error_code); | 421 | die(str, regs, error_code); |
401 | return; | 422 | return; |
402 | } | 423 | } |
403 | 424 | ||
404 | vm86_trap: { | 425 | vm86_trap: { |
405 | int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr); | 426 | int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr); |
406 | if (ret) goto trap_signal; | 427 | if (ret) goto trap_signal; |
407 | return; | 428 | return; |
408 | } | 429 | } |
409 | } | 430 | } |
410 | 431 | ||
411 | #define DO_ERROR(trapnr, signr, str, name) \ | 432 | #define DO_ERROR(trapnr, signr, str, name) \ |
412 | fastcall void do_##name(struct pt_regs * regs, long error_code) \ | 433 | fastcall void do_##name(struct pt_regs * regs, long error_code) \ |
413 | { \ | 434 | { \ |
414 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 435 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
415 | == NOTIFY_STOP) \ | 436 | == NOTIFY_STOP) \ |
416 | return; \ | 437 | return; \ |
417 | do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ | 438 | do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ |
418 | } | 439 | } |
419 | 440 | ||
420 | #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ | 441 | #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ |
421 | fastcall void do_##name(struct pt_regs * regs, long error_code) \ | 442 | fastcall void do_##name(struct pt_regs * regs, long error_code) \ |
422 | { \ | 443 | { \ |
423 | siginfo_t info; \ | 444 | siginfo_t info; \ |
424 | info.si_signo = signr; \ | 445 | info.si_signo = signr; \ |
425 | info.si_errno = 0; \ | 446 | info.si_errno = 0; \ |
426 | info.si_code = sicode; \ | 447 | info.si_code = sicode; \ |
427 | info.si_addr = (void __user *)siaddr; \ | 448 | info.si_addr = (void __user *)siaddr; \ |
428 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 449 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
429 | == NOTIFY_STOP) \ | 450 | == NOTIFY_STOP) \ |
430 | return; \ | 451 | return; \ |
431 | do_trap(trapnr, signr, str, 0, regs, error_code, &info); \ | 452 | do_trap(trapnr, signr, str, 0, regs, error_code, &info); \ |
432 | } | 453 | } |
433 | 454 | ||
434 | #define DO_VM86_ERROR(trapnr, signr, str, name) \ | 455 | #define DO_VM86_ERROR(trapnr, signr, str, name) \ |
435 | fastcall void do_##name(struct pt_regs * regs, long error_code) \ | 456 | fastcall void do_##name(struct pt_regs * regs, long error_code) \ |
436 | { \ | 457 | { \ |
437 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 458 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
438 | == NOTIFY_STOP) \ | 459 | == NOTIFY_STOP) \ |
439 | return; \ | 460 | return; \ |
440 | do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \ | 461 | do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \ |
441 | } | 462 | } |
442 | 463 | ||
443 | #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ | 464 | #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ |
444 | fastcall void do_##name(struct pt_regs * regs, long error_code) \ | 465 | fastcall void do_##name(struct pt_regs * regs, long error_code) \ |
445 | { \ | 466 | { \ |
446 | siginfo_t info; \ | 467 | siginfo_t info; \ |
447 | info.si_signo = signr; \ | 468 | info.si_signo = signr; \ |
448 | info.si_errno = 0; \ | 469 | info.si_errno = 0; \ |
449 | info.si_code = sicode; \ | 470 | info.si_code = sicode; \ |
450 | info.si_addr = (void __user *)siaddr; \ | 471 | info.si_addr = (void __user *)siaddr; \ |
451 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ | 472 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ |
452 | == NOTIFY_STOP) \ | 473 | == NOTIFY_STOP) \ |
453 | return; \ | 474 | return; \ |
454 | do_trap(trapnr, signr, str, 1, regs, error_code, &info); \ | 475 | do_trap(trapnr, signr, str, 1, regs, error_code, &info); \ |
455 | } | 476 | } |
456 | 477 | ||
457 | DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip) | 478 | DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip) |
458 | #ifndef CONFIG_KPROBES | 479 | #ifndef CONFIG_KPROBES |
459 | DO_VM86_ERROR( 3, SIGTRAP, "int3", int3) | 480 | DO_VM86_ERROR( 3, SIGTRAP, "int3", int3) |
460 | #endif | 481 | #endif |
461 | DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow) | 482 | DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow) |
462 | DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds) | 483 | DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds) |
463 | DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip) | 484 | DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip) |
464 | DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) | 485 | DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) |
465 | DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) | 486 | DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) |
466 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) | 487 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) |
467 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | 488 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) |
468 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) | 489 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) |
469 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0) | 490 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0) |
470 | 491 | ||
471 | fastcall void __kprobes do_general_protection(struct pt_regs * regs, | 492 | fastcall void __kprobes do_general_protection(struct pt_regs * regs, |
472 | long error_code) | 493 | long error_code) |
473 | { | 494 | { |
474 | int cpu = get_cpu(); | 495 | int cpu = get_cpu(); |
475 | struct tss_struct *tss = &per_cpu(init_tss, cpu); | 496 | struct tss_struct *tss = &per_cpu(init_tss, cpu); |
476 | struct thread_struct *thread = ¤t->thread; | 497 | struct thread_struct *thread = ¤t->thread; |
477 | 498 | ||
478 | /* | 499 | /* |
479 | * Perform the lazy TSS's I/O bitmap copy. If the TSS has an | 500 | * Perform the lazy TSS's I/O bitmap copy. If the TSS has an |
480 | * invalid offset set (the LAZY one) and the faulting thread has | 501 | * invalid offset set (the LAZY one) and the faulting thread has |
481 | * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS | 502 | * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS |
482 | * and we set the offset field correctly. Then we let the CPU to | 503 | * and we set the offset field correctly. Then we let the CPU to |
483 | * restart the faulting instruction. | 504 | * restart the faulting instruction. |
484 | */ | 505 | */ |
485 | if (tss->io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && | 506 | if (tss->io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && |
486 | thread->io_bitmap_ptr) { | 507 | thread->io_bitmap_ptr) { |
487 | memcpy(tss->io_bitmap, thread->io_bitmap_ptr, | 508 | memcpy(tss->io_bitmap, thread->io_bitmap_ptr, |
488 | thread->io_bitmap_max); | 509 | thread->io_bitmap_max); |
489 | /* | 510 | /* |
490 | * If the previously set map was extending to higher ports | 511 | * If the previously set map was extending to higher ports |
491 | * than the current one, pad extra space with 0xff (no access). | 512 | * than the current one, pad extra space with 0xff (no access). |
492 | */ | 513 | */ |
493 | if (thread->io_bitmap_max < tss->io_bitmap_max) | 514 | if (thread->io_bitmap_max < tss->io_bitmap_max) |
494 | memset((char *) tss->io_bitmap + | 515 | memset((char *) tss->io_bitmap + |
495 | thread->io_bitmap_max, 0xff, | 516 | thread->io_bitmap_max, 0xff, |
496 | tss->io_bitmap_max - thread->io_bitmap_max); | 517 | tss->io_bitmap_max - thread->io_bitmap_max); |
497 | tss->io_bitmap_max = thread->io_bitmap_max; | 518 | tss->io_bitmap_max = thread->io_bitmap_max; |
498 | tss->io_bitmap_base = IO_BITMAP_OFFSET; | 519 | tss->io_bitmap_base = IO_BITMAP_OFFSET; |
499 | tss->io_bitmap_owner = thread; | 520 | tss->io_bitmap_owner = thread; |
500 | put_cpu(); | 521 | put_cpu(); |
501 | return; | 522 | return; |
502 | } | 523 | } |
503 | put_cpu(); | 524 | put_cpu(); |
504 | 525 | ||
505 | current->thread.error_code = error_code; | 526 | current->thread.error_code = error_code; |
506 | current->thread.trap_no = 13; | 527 | current->thread.trap_no = 13; |
507 | 528 | ||
508 | if (regs->eflags & VM_MASK) | 529 | if (regs->eflags & VM_MASK) |
509 | goto gp_in_vm86; | 530 | goto gp_in_vm86; |
510 | 531 | ||
511 | if (!user_mode(regs)) | 532 | if (!user_mode(regs)) |
512 | goto gp_in_kernel; | 533 | goto gp_in_kernel; |
513 | 534 | ||
514 | current->thread.error_code = error_code; | 535 | current->thread.error_code = error_code; |
515 | current->thread.trap_no = 13; | 536 | current->thread.trap_no = 13; |
516 | force_sig(SIGSEGV, current); | 537 | force_sig(SIGSEGV, current); |
517 | return; | 538 | return; |
518 | 539 | ||
519 | gp_in_vm86: | 540 | gp_in_vm86: |
520 | local_irq_enable(); | 541 | local_irq_enable(); |
521 | handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); | 542 | handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); |
522 | return; | 543 | return; |
523 | 544 | ||
524 | gp_in_kernel: | 545 | gp_in_kernel: |
525 | if (!fixup_exception(regs)) { | 546 | if (!fixup_exception(regs)) { |
526 | if (notify_die(DIE_GPF, "general protection fault", regs, | 547 | if (notify_die(DIE_GPF, "general protection fault", regs, |
527 | error_code, 13, SIGSEGV) == NOTIFY_STOP) | 548 | error_code, 13, SIGSEGV) == NOTIFY_STOP) |
528 | return; | 549 | return; |
529 | die("general protection fault", regs, error_code); | 550 | die("general protection fault", regs, error_code); |
530 | } | 551 | } |
531 | } | 552 | } |
532 | 553 | ||
533 | static void mem_parity_error(unsigned char reason, struct pt_regs * regs) | 554 | static void mem_parity_error(unsigned char reason, struct pt_regs * regs) |
534 | { | 555 | { |
535 | printk(KERN_EMERG "Uhhuh. NMI received. Dazed and confused, but trying " | 556 | printk(KERN_EMERG "Uhhuh. NMI received. Dazed and confused, but trying " |
536 | "to continue\n"); | 557 | "to continue\n"); |
537 | printk(KERN_EMERG "You probably have a hardware problem with your RAM " | 558 | printk(KERN_EMERG "You probably have a hardware problem with your RAM " |
538 | "chips\n"); | 559 | "chips\n"); |
539 | 560 | ||
540 | /* Clear and disable the memory parity error line. */ | 561 | /* Clear and disable the memory parity error line. */ |
541 | clear_mem_error(reason); | 562 | clear_mem_error(reason); |
542 | } | 563 | } |
543 | 564 | ||
544 | static void io_check_error(unsigned char reason, struct pt_regs * regs) | 565 | static void io_check_error(unsigned char reason, struct pt_regs * regs) |
545 | { | 566 | { |
546 | unsigned long i; | 567 | unsigned long i; |
547 | 568 | ||
548 | printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); | 569 | printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); |
549 | show_registers(regs); | 570 | show_registers(regs); |
550 | 571 | ||
551 | /* Re-enable the IOCK line, wait for a few seconds */ | 572 | /* Re-enable the IOCK line, wait for a few seconds */ |
552 | reason = (reason & 0xf) | 8; | 573 | reason = (reason & 0xf) | 8; |
553 | outb(reason, 0x61); | 574 | outb(reason, 0x61); |
554 | i = 2000; | 575 | i = 2000; |
555 | while (--i) udelay(1000); | 576 | while (--i) udelay(1000); |
556 | reason &= ~8; | 577 | reason &= ~8; |
557 | outb(reason, 0x61); | 578 | outb(reason, 0x61); |
558 | } | 579 | } |
559 | 580 | ||
560 | static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | 581 | static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) |
561 | { | 582 | { |
562 | #ifdef CONFIG_MCA | 583 | #ifdef CONFIG_MCA |
563 | /* Might actually be able to figure out what the guilty party | 584 | /* Might actually be able to figure out what the guilty party |
564 | * is. */ | 585 | * is. */ |
565 | if( MCA_bus ) { | 586 | if( MCA_bus ) { |
566 | mca_handle_nmi(); | 587 | mca_handle_nmi(); |
567 | return; | 588 | return; |
568 | } | 589 | } |
569 | #endif | 590 | #endif |
570 | printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", | 591 | printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", |
571 | reason, smp_processor_id()); | 592 | reason, smp_processor_id()); |
572 | printk("Dazed and confused, but trying to continue\n"); | 593 | printk("Dazed and confused, but trying to continue\n"); |
573 | printk("Do you have a strange power saving mode enabled?\n"); | 594 | printk("Do you have a strange power saving mode enabled?\n"); |
574 | } | 595 | } |
575 | 596 | ||
576 | static DEFINE_SPINLOCK(nmi_print_lock); | 597 | static DEFINE_SPINLOCK(nmi_print_lock); |
577 | 598 | ||
578 | void die_nmi (struct pt_regs *regs, const char *msg) | 599 | void die_nmi (struct pt_regs *regs, const char *msg) |
579 | { | 600 | { |
580 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) == | 601 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) == |
581 | NOTIFY_STOP) | 602 | NOTIFY_STOP) |
582 | return; | 603 | return; |
583 | 604 | ||
584 | spin_lock(&nmi_print_lock); | 605 | spin_lock(&nmi_print_lock); |
585 | /* | 606 | /* |
586 | * We are in trouble anyway, lets at least try | 607 | * We are in trouble anyway, lets at least try |
587 | * to get a message out. | 608 | * to get a message out. |
588 | */ | 609 | */ |
589 | bust_spinlocks(1); | 610 | bust_spinlocks(1); |
590 | printk(KERN_EMERG "%s", msg); | 611 | printk(KERN_EMERG "%s", msg); |
591 | printk(" on CPU%d, eip %08lx, registers:\n", | 612 | printk(" on CPU%d, eip %08lx, registers:\n", |
592 | smp_processor_id(), regs->eip); | 613 | smp_processor_id(), regs->eip); |
593 | show_registers(regs); | 614 | show_registers(regs); |
594 | printk(KERN_EMERG "console shuts up ...\n"); | 615 | printk(KERN_EMERG "console shuts up ...\n"); |
595 | console_silent(); | 616 | console_silent(); |
596 | spin_unlock(&nmi_print_lock); | 617 | spin_unlock(&nmi_print_lock); |
597 | bust_spinlocks(0); | 618 | bust_spinlocks(0); |
598 | 619 | ||
599 | /* If we are in kernel we are probably nested up pretty bad | 620 | /* If we are in kernel we are probably nested up pretty bad |
600 | * and might aswell get out now while we still can. | 621 | * and might aswell get out now while we still can. |
601 | */ | 622 | */ |
602 | if (!user_mode(regs)) { | 623 | if (!user_mode(regs)) { |
603 | current->thread.trap_no = 2; | 624 | current->thread.trap_no = 2; |
604 | crash_kexec(regs); | 625 | crash_kexec(regs); |
605 | } | 626 | } |
606 | 627 | ||
607 | do_exit(SIGSEGV); | 628 | do_exit(SIGSEGV); |
608 | } | 629 | } |
609 | 630 | ||
610 | static void default_do_nmi(struct pt_regs * regs) | 631 | static void default_do_nmi(struct pt_regs * regs) |
611 | { | 632 | { |
612 | unsigned char reason = 0; | 633 | unsigned char reason = 0; |
613 | 634 | ||
614 | /* Only the BSP gets external NMIs from the system. */ | 635 | /* Only the BSP gets external NMIs from the system. */ |
615 | if (!smp_processor_id()) | 636 | if (!smp_processor_id()) |
616 | reason = get_nmi_reason(); | 637 | reason = get_nmi_reason(); |
617 | 638 | ||
618 | if (!(reason & 0xc0)) { | 639 | if (!(reason & 0xc0)) { |
619 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) | 640 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) |
620 | == NOTIFY_STOP) | 641 | == NOTIFY_STOP) |
621 | return; | 642 | return; |
622 | #ifdef CONFIG_X86_LOCAL_APIC | 643 | #ifdef CONFIG_X86_LOCAL_APIC |
623 | /* | 644 | /* |
624 | * Ok, so this is none of the documented NMI sources, | 645 | * Ok, so this is none of the documented NMI sources, |
625 | * so it must be the NMI watchdog. | 646 | * so it must be the NMI watchdog. |
626 | */ | 647 | */ |
627 | if (nmi_watchdog) { | 648 | if (nmi_watchdog) { |
628 | nmi_watchdog_tick(regs); | 649 | nmi_watchdog_tick(regs); |
629 | return; | 650 | return; |
630 | } | 651 | } |
631 | #endif | 652 | #endif |
632 | unknown_nmi_error(reason, regs); | 653 | unknown_nmi_error(reason, regs); |
633 | return; | 654 | return; |
634 | } | 655 | } |
635 | if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP) | 656 | if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP) |
636 | return; | 657 | return; |
637 | if (reason & 0x80) | 658 | if (reason & 0x80) |
638 | mem_parity_error(reason, regs); | 659 | mem_parity_error(reason, regs); |
639 | if (reason & 0x40) | 660 | if (reason & 0x40) |
640 | io_check_error(reason, regs); | 661 | io_check_error(reason, regs); |
641 | /* | 662 | /* |
642 | * Reassert NMI in case it became active meanwhile | 663 | * Reassert NMI in case it became active meanwhile |
643 | * as it's edge-triggered. | 664 | * as it's edge-triggered. |
644 | */ | 665 | */ |
645 | reassert_nmi(); | 666 | reassert_nmi(); |
646 | } | 667 | } |
647 | 668 | ||
648 | static int dummy_nmi_callback(struct pt_regs * regs, int cpu) | 669 | static int dummy_nmi_callback(struct pt_regs * regs, int cpu) |
649 | { | 670 | { |
650 | return 0; | 671 | return 0; |
651 | } | 672 | } |
652 | 673 | ||
653 | static nmi_callback_t nmi_callback = dummy_nmi_callback; | 674 | static nmi_callback_t nmi_callback = dummy_nmi_callback; |
654 | 675 | ||
655 | fastcall void do_nmi(struct pt_regs * regs, long error_code) | 676 | fastcall void do_nmi(struct pt_regs * regs, long error_code) |
656 | { | 677 | { |
657 | int cpu; | 678 | int cpu; |
658 | 679 | ||
659 | nmi_enter(); | 680 | nmi_enter(); |
660 | 681 | ||
661 | cpu = smp_processor_id(); | 682 | cpu = smp_processor_id(); |
662 | 683 | ||
663 | ++nmi_count(cpu); | 684 | ++nmi_count(cpu); |
664 | 685 | ||
665 | if (!rcu_dereference(nmi_callback)(regs, cpu)) | 686 | if (!rcu_dereference(nmi_callback)(regs, cpu)) |
666 | default_do_nmi(regs); | 687 | default_do_nmi(regs); |
667 | 688 | ||
668 | nmi_exit(); | 689 | nmi_exit(); |
669 | } | 690 | } |
670 | 691 | ||
671 | void set_nmi_callback(nmi_callback_t callback) | 692 | void set_nmi_callback(nmi_callback_t callback) |
672 | { | 693 | { |
673 | rcu_assign_pointer(nmi_callback, callback); | 694 | rcu_assign_pointer(nmi_callback, callback); |
674 | } | 695 | } |
675 | EXPORT_SYMBOL_GPL(set_nmi_callback); | 696 | EXPORT_SYMBOL_GPL(set_nmi_callback); |
676 | 697 | ||
677 | void unset_nmi_callback(void) | 698 | void unset_nmi_callback(void) |
678 | { | 699 | { |
679 | nmi_callback = dummy_nmi_callback; | 700 | nmi_callback = dummy_nmi_callback; |
680 | } | 701 | } |
681 | EXPORT_SYMBOL_GPL(unset_nmi_callback); | 702 | EXPORT_SYMBOL_GPL(unset_nmi_callback); |
682 | 703 | ||
683 | #ifdef CONFIG_KPROBES | 704 | #ifdef CONFIG_KPROBES |
684 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) | 705 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) |
685 | { | 706 | { |
686 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | 707 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) |
687 | == NOTIFY_STOP) | 708 | == NOTIFY_STOP) |
688 | return; | 709 | return; |
689 | /* This is an interrupt gate, because kprobes wants interrupts | 710 | /* This is an interrupt gate, because kprobes wants interrupts |
690 | disabled. Normal trap handlers don't. */ | 711 | disabled. Normal trap handlers don't. */ |
691 | restore_interrupts(regs); | 712 | restore_interrupts(regs); |
692 | do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); | 713 | do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); |
693 | } | 714 | } |
694 | #endif | 715 | #endif |
695 | 716 | ||
696 | /* | 717 | /* |
697 | * Our handling of the processor debug registers is non-trivial. | 718 | * Our handling of the processor debug registers is non-trivial. |
698 | * We do not clear them on entry and exit from the kernel. Therefore | 719 | * We do not clear them on entry and exit from the kernel. Therefore |
699 | * it is possible to get a watchpoint trap here from inside the kernel. | 720 | * it is possible to get a watchpoint trap here from inside the kernel. |
700 | * However, the code in ./ptrace.c has ensured that the user can | 721 | * However, the code in ./ptrace.c has ensured that the user can |
701 | * only set watchpoints on userspace addresses. Therefore the in-kernel | 722 | * only set watchpoints on userspace addresses. Therefore the in-kernel |
702 | * watchpoint trap can only occur in code which is reading/writing | 723 | * watchpoint trap can only occur in code which is reading/writing |
703 | * from user space. Such code must not hold kernel locks (since it | 724 | * from user space. Such code must not hold kernel locks (since it |
704 | * can equally take a page fault), therefore it is safe to call | 725 | * can equally take a page fault), therefore it is safe to call |
705 | * force_sig_info even though that claims and releases locks. | 726 | * force_sig_info even though that claims and releases locks. |
706 | * | 727 | * |
707 | * Code in ./signal.c ensures that the debug control register | 728 | * Code in ./signal.c ensures that the debug control register |
708 | * is restored before we deliver any signal, and therefore that | 729 | * is restored before we deliver any signal, and therefore that |
709 | * user code runs with the correct debug control register even though | 730 | * user code runs with the correct debug control register even though |
710 | * we clear it here. | 731 | * we clear it here. |
711 | * | 732 | * |
712 | * Being careful here means that we don't have to be as careful in a | 733 | * Being careful here means that we don't have to be as careful in a |
713 | * lot of more complicated places (task switching can be a bit lazy | 734 | * lot of more complicated places (task switching can be a bit lazy |
714 | * about restoring all the debug state, and ptrace doesn't have to | 735 | * about restoring all the debug state, and ptrace doesn't have to |
715 | * find every occurrence of the TF bit that could be saved away even | 736 | * find every occurrence of the TF bit that could be saved away even |
716 | * by user code) | 737 | * by user code) |
717 | */ | 738 | */ |
718 | fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code) | 739 | fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code) |
719 | { | 740 | { |
720 | unsigned int condition; | 741 | unsigned int condition; |
721 | struct task_struct *tsk = current; | 742 | struct task_struct *tsk = current; |
722 | 743 | ||
723 | get_debugreg(condition, 6); | 744 | get_debugreg(condition, 6); |
724 | 745 | ||
725 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, | 746 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, |
726 | SIGTRAP) == NOTIFY_STOP) | 747 | SIGTRAP) == NOTIFY_STOP) |
727 | return; | 748 | return; |
728 | /* It's safe to allow irq's after DR6 has been saved */ | 749 | /* It's safe to allow irq's after DR6 has been saved */ |
729 | if (regs->eflags & X86_EFLAGS_IF) | 750 | if (regs->eflags & X86_EFLAGS_IF) |
730 | local_irq_enable(); | 751 | local_irq_enable(); |
731 | 752 | ||
732 | /* Mask out spurious debug traps due to lazy DR7 setting */ | 753 | /* Mask out spurious debug traps due to lazy DR7 setting */ |
733 | if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { | 754 | if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { |
734 | if (!tsk->thread.debugreg[7]) | 755 | if (!tsk->thread.debugreg[7]) |
735 | goto clear_dr7; | 756 | goto clear_dr7; |
736 | } | 757 | } |
737 | 758 | ||
738 | if (regs->eflags & VM_MASK) | 759 | if (regs->eflags & VM_MASK) |
739 | goto debug_vm86; | 760 | goto debug_vm86; |
740 | 761 | ||
741 | /* Save debug status register where ptrace can see it */ | 762 | /* Save debug status register where ptrace can see it */ |
742 | tsk->thread.debugreg[6] = condition; | 763 | tsk->thread.debugreg[6] = condition; |
743 | 764 | ||
744 | /* | 765 | /* |
745 | * Single-stepping through TF: make sure we ignore any events in | 766 | * Single-stepping through TF: make sure we ignore any events in |
746 | * kernel space (but re-enable TF when returning to user mode). | 767 | * kernel space (but re-enable TF when returning to user mode). |
747 | */ | 768 | */ |
748 | if (condition & DR_STEP) { | 769 | if (condition & DR_STEP) { |
749 | /* | 770 | /* |
750 | * We already checked v86 mode above, so we can | 771 | * We already checked v86 mode above, so we can |
751 | * check for kernel mode by just checking the CPL | 772 | * check for kernel mode by just checking the CPL |
752 | * of CS. | 773 | * of CS. |
753 | */ | 774 | */ |
754 | if (!user_mode(regs)) | 775 | if (!user_mode(regs)) |
755 | goto clear_TF_reenable; | 776 | goto clear_TF_reenable; |
756 | } | 777 | } |
757 | 778 | ||
758 | /* Ok, finally something we can handle */ | 779 | /* Ok, finally something we can handle */ |
759 | send_sigtrap(tsk, regs, error_code); | 780 | send_sigtrap(tsk, regs, error_code); |
760 | 781 | ||
761 | /* Disable additional traps. They'll be re-enabled when | 782 | /* Disable additional traps. They'll be re-enabled when |
762 | * the signal is delivered. | 783 | * the signal is delivered. |
763 | */ | 784 | */ |
764 | clear_dr7: | 785 | clear_dr7: |
765 | set_debugreg(0, 7); | 786 | set_debugreg(0, 7); |
766 | return; | 787 | return; |
767 | 788 | ||
768 | debug_vm86: | 789 | debug_vm86: |
769 | handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); | 790 | handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); |
770 | return; | 791 | return; |
771 | 792 | ||
772 | clear_TF_reenable: | 793 | clear_TF_reenable: |
773 | set_tsk_thread_flag(tsk, TIF_SINGLESTEP); | 794 | set_tsk_thread_flag(tsk, TIF_SINGLESTEP); |
774 | regs->eflags &= ~TF_MASK; | 795 | regs->eflags &= ~TF_MASK; |
775 | return; | 796 | return; |
776 | } | 797 | } |
777 | 798 | ||
778 | /* | 799 | /* |
779 | * Note that we play around with the 'TS' bit in an attempt to get | 800 | * Note that we play around with the 'TS' bit in an attempt to get |
780 | * the correct behaviour even in the presence of the asynchronous | 801 | * the correct behaviour even in the presence of the asynchronous |
781 | * IRQ13 behaviour | 802 | * IRQ13 behaviour |
782 | */ | 803 | */ |
783 | void math_error(void __user *eip) | 804 | void math_error(void __user *eip) |
784 | { | 805 | { |
785 | struct task_struct * task; | 806 | struct task_struct * task; |
786 | siginfo_t info; | 807 | siginfo_t info; |
787 | unsigned short cwd, swd; | 808 | unsigned short cwd, swd; |
788 | 809 | ||
789 | /* | 810 | /* |
790 | * Save the info for the exception handler and clear the error. | 811 | * Save the info for the exception handler and clear the error. |
791 | */ | 812 | */ |
792 | task = current; | 813 | task = current; |
793 | save_init_fpu(task); | 814 | save_init_fpu(task); |
794 | task->thread.trap_no = 16; | 815 | task->thread.trap_no = 16; |
795 | task->thread.error_code = 0; | 816 | task->thread.error_code = 0; |
796 | info.si_signo = SIGFPE; | 817 | info.si_signo = SIGFPE; |
797 | info.si_errno = 0; | 818 | info.si_errno = 0; |
798 | info.si_code = __SI_FAULT; | 819 | info.si_code = __SI_FAULT; |
799 | info.si_addr = eip; | 820 | info.si_addr = eip; |
800 | /* | 821 | /* |
801 | * (~cwd & swd) will mask out exceptions that are not set to unmasked | 822 | * (~cwd & swd) will mask out exceptions that are not set to unmasked |
802 | * status. 0x3f is the exception bits in these regs, 0x200 is the | 823 | * status. 0x3f is the exception bits in these regs, 0x200 is the |
803 | * C1 reg you need in case of a stack fault, 0x040 is the stack | 824 | * C1 reg you need in case of a stack fault, 0x040 is the stack |
804 | * fault bit. We should only be taking one exception at a time, | 825 | * fault bit. We should only be taking one exception at a time, |
805 | * so if this combination doesn't produce any single exception, | 826 | * so if this combination doesn't produce any single exception, |
806 | * then we have a bad program that isn't syncronizing its FPU usage | 827 | * then we have a bad program that isn't syncronizing its FPU usage |
807 | * and it will suffer the consequences since we won't be able to | 828 | * and it will suffer the consequences since we won't be able to |
808 | * fully reproduce the context of the exception | 829 | * fully reproduce the context of the exception |
809 | */ | 830 | */ |
810 | cwd = get_fpu_cwd(task); | 831 | cwd = get_fpu_cwd(task); |
811 | swd = get_fpu_swd(task); | 832 | swd = get_fpu_swd(task); |
812 | switch (swd & ~cwd & 0x3f) { | 833 | switch (swd & ~cwd & 0x3f) { |
813 | case 0x000: /* No unmasked exception */ | 834 | case 0x000: /* No unmasked exception */ |
814 | return; | 835 | return; |
815 | default: /* Multiple exceptions */ | 836 | default: /* Multiple exceptions */ |
816 | break; | 837 | break; |
817 | case 0x001: /* Invalid Op */ | 838 | case 0x001: /* Invalid Op */ |
818 | /* | 839 | /* |
819 | * swd & 0x240 == 0x040: Stack Underflow | 840 | * swd & 0x240 == 0x040: Stack Underflow |
820 | * swd & 0x240 == 0x240: Stack Overflow | 841 | * swd & 0x240 == 0x240: Stack Overflow |
821 | * User must clear the SF bit (0x40) if set | 842 | * User must clear the SF bit (0x40) if set |
822 | */ | 843 | */ |
823 | info.si_code = FPE_FLTINV; | 844 | info.si_code = FPE_FLTINV; |
824 | break; | 845 | break; |
825 | case 0x002: /* Denormalize */ | 846 | case 0x002: /* Denormalize */ |
826 | case 0x010: /* Underflow */ | 847 | case 0x010: /* Underflow */ |
827 | info.si_code = FPE_FLTUND; | 848 | info.si_code = FPE_FLTUND; |
828 | break; | 849 | break; |
829 | case 0x004: /* Zero Divide */ | 850 | case 0x004: /* Zero Divide */ |
830 | info.si_code = FPE_FLTDIV; | 851 | info.si_code = FPE_FLTDIV; |
831 | break; | 852 | break; |
832 | case 0x008: /* Overflow */ | 853 | case 0x008: /* Overflow */ |
833 | info.si_code = FPE_FLTOVF; | 854 | info.si_code = FPE_FLTOVF; |
834 | break; | 855 | break; |
835 | case 0x020: /* Precision */ | 856 | case 0x020: /* Precision */ |
836 | info.si_code = FPE_FLTRES; | 857 | info.si_code = FPE_FLTRES; |
837 | break; | 858 | break; |
838 | } | 859 | } |
839 | force_sig_info(SIGFPE, &info, task); | 860 | force_sig_info(SIGFPE, &info, task); |
840 | } | 861 | } |
841 | 862 | ||
842 | fastcall void do_coprocessor_error(struct pt_regs * regs, long error_code) | 863 | fastcall void do_coprocessor_error(struct pt_regs * regs, long error_code) |
843 | { | 864 | { |
844 | ignore_fpu_irq = 1; | 865 | ignore_fpu_irq = 1; |
845 | math_error((void __user *)regs->eip); | 866 | math_error((void __user *)regs->eip); |
846 | } | 867 | } |
847 | 868 | ||
848 | static void simd_math_error(void __user *eip) | 869 | static void simd_math_error(void __user *eip) |
849 | { | 870 | { |
850 | struct task_struct * task; | 871 | struct task_struct * task; |
851 | siginfo_t info; | 872 | siginfo_t info; |
852 | unsigned short mxcsr; | 873 | unsigned short mxcsr; |
853 | 874 | ||
854 | /* | 875 | /* |
855 | * Save the info for the exception handler and clear the error. | 876 | * Save the info for the exception handler and clear the error. |
856 | */ | 877 | */ |
857 | task = current; | 878 | task = current; |
858 | save_init_fpu(task); | 879 | save_init_fpu(task); |
859 | task->thread.trap_no = 19; | 880 | task->thread.trap_no = 19; |
860 | task->thread.error_code = 0; | 881 | task->thread.error_code = 0; |
861 | info.si_signo = SIGFPE; | 882 | info.si_signo = SIGFPE; |
862 | info.si_errno = 0; | 883 | info.si_errno = 0; |
863 | info.si_code = __SI_FAULT; | 884 | info.si_code = __SI_FAULT; |
864 | info.si_addr = eip; | 885 | info.si_addr = eip; |
865 | /* | 886 | /* |
866 | * The SIMD FPU exceptions are handled a little differently, as there | 887 | * The SIMD FPU exceptions are handled a little differently, as there |
867 | * is only a single status/control register. Thus, to determine which | 888 | * is only a single status/control register. Thus, to determine which |
868 | * unmasked exception was caught we must mask the exception mask bits | 889 | * unmasked exception was caught we must mask the exception mask bits |
869 | * at 0x1f80, and then use these to mask the exception bits at 0x3f. | 890 | * at 0x1f80, and then use these to mask the exception bits at 0x3f. |
870 | */ | 891 | */ |
871 | mxcsr = get_fpu_mxcsr(task); | 892 | mxcsr = get_fpu_mxcsr(task); |
872 | switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) { | 893 | switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) { |
873 | case 0x000: | 894 | case 0x000: |
874 | default: | 895 | default: |
875 | break; | 896 | break; |
876 | case 0x001: /* Invalid Op */ | 897 | case 0x001: /* Invalid Op */ |
877 | info.si_code = FPE_FLTINV; | 898 | info.si_code = FPE_FLTINV; |
878 | break; | 899 | break; |
879 | case 0x002: /* Denormalize */ | 900 | case 0x002: /* Denormalize */ |
880 | case 0x010: /* Underflow */ | 901 | case 0x010: /* Underflow */ |
881 | info.si_code = FPE_FLTUND; | 902 | info.si_code = FPE_FLTUND; |
882 | break; | 903 | break; |
883 | case 0x004: /* Zero Divide */ | 904 | case 0x004: /* Zero Divide */ |
884 | info.si_code = FPE_FLTDIV; | 905 | info.si_code = FPE_FLTDIV; |
885 | break; | 906 | break; |
886 | case 0x008: /* Overflow */ | 907 | case 0x008: /* Overflow */ |
887 | info.si_code = FPE_FLTOVF; | 908 | info.si_code = FPE_FLTOVF; |
888 | break; | 909 | break; |
889 | case 0x020: /* Precision */ | 910 | case 0x020: /* Precision */ |
890 | info.si_code = FPE_FLTRES; | 911 | info.si_code = FPE_FLTRES; |
891 | break; | 912 | break; |
892 | } | 913 | } |
893 | force_sig_info(SIGFPE, &info, task); | 914 | force_sig_info(SIGFPE, &info, task); |
894 | } | 915 | } |
895 | 916 | ||
896 | fastcall void do_simd_coprocessor_error(struct pt_regs * regs, | 917 | fastcall void do_simd_coprocessor_error(struct pt_regs * regs, |
897 | long error_code) | 918 | long error_code) |
898 | { | 919 | { |
899 | if (cpu_has_xmm) { | 920 | if (cpu_has_xmm) { |
900 | /* Handle SIMD FPU exceptions on PIII+ processors. */ | 921 | /* Handle SIMD FPU exceptions on PIII+ processors. */ |
901 | ignore_fpu_irq = 1; | 922 | ignore_fpu_irq = 1; |
902 | simd_math_error((void __user *)regs->eip); | 923 | simd_math_error((void __user *)regs->eip); |
903 | } else { | 924 | } else { |
904 | /* | 925 | /* |
905 | * Handle strange cache flush from user space exception | 926 | * Handle strange cache flush from user space exception |
906 | * in all other cases. This is undocumented behaviour. | 927 | * in all other cases. This is undocumented behaviour. |
907 | */ | 928 | */ |
908 | if (regs->eflags & VM_MASK) { | 929 | if (regs->eflags & VM_MASK) { |
909 | handle_vm86_fault((struct kernel_vm86_regs *)regs, | 930 | handle_vm86_fault((struct kernel_vm86_regs *)regs, |
910 | error_code); | 931 | error_code); |
911 | return; | 932 | return; |
912 | } | 933 | } |
913 | current->thread.trap_no = 19; | 934 | current->thread.trap_no = 19; |
914 | current->thread.error_code = error_code; | 935 | current->thread.error_code = error_code; |
915 | die_if_kernel("cache flush denied", regs, error_code); | 936 | die_if_kernel("cache flush denied", regs, error_code); |
916 | force_sig(SIGSEGV, current); | 937 | force_sig(SIGSEGV, current); |
917 | } | 938 | } |
918 | } | 939 | } |
919 | 940 | ||
920 | fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, | 941 | fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, |
921 | long error_code) | 942 | long error_code) |
922 | { | 943 | { |
923 | #if 0 | 944 | #if 0 |
924 | /* No need to warn about this any longer. */ | 945 | /* No need to warn about this any longer. */ |
925 | printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); | 946 | printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); |
926 | #endif | 947 | #endif |
927 | } | 948 | } |
928 | 949 | ||
929 | fastcall void setup_x86_bogus_stack(unsigned char * stk) | 950 | fastcall void setup_x86_bogus_stack(unsigned char * stk) |
930 | { | 951 | { |
931 | unsigned long *switch16_ptr, *switch32_ptr; | 952 | unsigned long *switch16_ptr, *switch32_ptr; |
932 | struct pt_regs *regs; | 953 | struct pt_regs *regs; |
933 | unsigned long stack_top, stack_bot; | 954 | unsigned long stack_top, stack_bot; |
934 | unsigned short iret_frame16_off; | 955 | unsigned short iret_frame16_off; |
935 | int cpu = smp_processor_id(); | 956 | int cpu = smp_processor_id(); |
936 | /* reserve the space on 32bit stack for the magic switch16 pointer */ | 957 | /* reserve the space on 32bit stack for the magic switch16 pointer */ |
937 | memmove(stk, stk + 8, sizeof(struct pt_regs)); | 958 | memmove(stk, stk + 8, sizeof(struct pt_regs)); |
938 | switch16_ptr = (unsigned long *)(stk + sizeof(struct pt_regs)); | 959 | switch16_ptr = (unsigned long *)(stk + sizeof(struct pt_regs)); |
939 | regs = (struct pt_regs *)stk; | 960 | regs = (struct pt_regs *)stk; |
940 | /* now the switch32 on 16bit stack */ | 961 | /* now the switch32 on 16bit stack */ |
941 | stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu); | 962 | stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu); |
942 | stack_top = stack_bot + CPU_16BIT_STACK_SIZE; | 963 | stack_top = stack_bot + CPU_16BIT_STACK_SIZE; |
943 | switch32_ptr = (unsigned long *)(stack_top - 8); | 964 | switch32_ptr = (unsigned long *)(stack_top - 8); |
944 | iret_frame16_off = CPU_16BIT_STACK_SIZE - 8 - 20; | 965 | iret_frame16_off = CPU_16BIT_STACK_SIZE - 8 - 20; |
945 | /* copy iret frame on 16bit stack */ | 966 | /* copy iret frame on 16bit stack */ |
946 | memcpy((void *)(stack_bot + iret_frame16_off), ®s->eip, 20); | 967 | memcpy((void *)(stack_bot + iret_frame16_off), ®s->eip, 20); |
947 | /* fill in the switch pointers */ | 968 | /* fill in the switch pointers */ |
948 | switch16_ptr[0] = (regs->esp & 0xffff0000) | iret_frame16_off; | 969 | switch16_ptr[0] = (regs->esp & 0xffff0000) | iret_frame16_off; |
949 | switch16_ptr[1] = __ESPFIX_SS; | 970 | switch16_ptr[1] = __ESPFIX_SS; |
950 | switch32_ptr[0] = (unsigned long)stk + sizeof(struct pt_regs) + | 971 | switch32_ptr[0] = (unsigned long)stk + sizeof(struct pt_regs) + |
951 | 8 - CPU_16BIT_STACK_SIZE; | 972 | 8 - CPU_16BIT_STACK_SIZE; |
952 | switch32_ptr[1] = __KERNEL_DS; | 973 | switch32_ptr[1] = __KERNEL_DS; |
953 | } | 974 | } |
954 | 975 | ||
955 | fastcall unsigned char * fixup_x86_bogus_stack(unsigned short sp) | 976 | fastcall unsigned char * fixup_x86_bogus_stack(unsigned short sp) |
956 | { | 977 | { |
957 | unsigned long *switch32_ptr; | 978 | unsigned long *switch32_ptr; |
958 | unsigned char *stack16, *stack32; | 979 | unsigned char *stack16, *stack32; |
959 | unsigned long stack_top, stack_bot; | 980 | unsigned long stack_top, stack_bot; |
960 | int len; | 981 | int len; |
961 | int cpu = smp_processor_id(); | 982 | int cpu = smp_processor_id(); |
962 | stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu); | 983 | stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu); |
963 | stack_top = stack_bot + CPU_16BIT_STACK_SIZE; | 984 | stack_top = stack_bot + CPU_16BIT_STACK_SIZE; |
964 | switch32_ptr = (unsigned long *)(stack_top - 8); | 985 | switch32_ptr = (unsigned long *)(stack_top - 8); |
965 | /* copy the data from 16bit stack to 32bit stack */ | 986 | /* copy the data from 16bit stack to 32bit stack */ |
966 | len = CPU_16BIT_STACK_SIZE - 8 - sp; | 987 | len = CPU_16BIT_STACK_SIZE - 8 - sp; |
967 | stack16 = (unsigned char *)(stack_bot + sp); | 988 | stack16 = (unsigned char *)(stack_bot + sp); |
968 | stack32 = (unsigned char *) | 989 | stack32 = (unsigned char *) |
969 | (switch32_ptr[0] + CPU_16BIT_STACK_SIZE - 8 - len); | 990 | (switch32_ptr[0] + CPU_16BIT_STACK_SIZE - 8 - len); |
970 | memcpy(stack32, stack16, len); | 991 | memcpy(stack32, stack16, len); |
971 | return stack32; | 992 | return stack32; |
972 | } | 993 | } |
973 | 994 | ||
974 | /* | 995 | /* |
975 | * 'math_state_restore()' saves the current math information in the | 996 | * 'math_state_restore()' saves the current math information in the |
976 | * old math state array, and gets the new ones from the current task | 997 | * old math state array, and gets the new ones from the current task |
977 | * | 998 | * |
978 | * Careful.. There are problems with IBM-designed IRQ13 behaviour. | 999 | * Careful.. There are problems with IBM-designed IRQ13 behaviour. |
979 | * Don't touch unless you *really* know how it works. | 1000 | * Don't touch unless you *really* know how it works. |
980 | * | 1001 | * |
981 | * Must be called with kernel preemption disabled (in this case, | 1002 | * Must be called with kernel preemption disabled (in this case, |
982 | * local interrupts are disabled at the call-site in entry.S). | 1003 | * local interrupts are disabled at the call-site in entry.S). |
983 | */ | 1004 | */ |
984 | asmlinkage void math_state_restore(struct pt_regs regs) | 1005 | asmlinkage void math_state_restore(struct pt_regs regs) |
985 | { | 1006 | { |
986 | struct thread_info *thread = current_thread_info(); | 1007 | struct thread_info *thread = current_thread_info(); |
987 | struct task_struct *tsk = thread->task; | 1008 | struct task_struct *tsk = thread->task; |
988 | 1009 | ||
989 | clts(); /* Allow maths ops (or we recurse) */ | 1010 | clts(); /* Allow maths ops (or we recurse) */ |
990 | if (!tsk_used_math(tsk)) | 1011 | if (!tsk_used_math(tsk)) |
991 | init_fpu(tsk); | 1012 | init_fpu(tsk); |
992 | restore_fpu(tsk); | 1013 | restore_fpu(tsk); |
993 | thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ | 1014 | thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ |
994 | } | 1015 | } |
995 | 1016 | ||
996 | #ifndef CONFIG_MATH_EMULATION | 1017 | #ifndef CONFIG_MATH_EMULATION |
997 | 1018 | ||
998 | asmlinkage void math_emulate(long arg) | 1019 | asmlinkage void math_emulate(long arg) |
999 | { | 1020 | { |
1000 | printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n"); | 1021 | printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n"); |
1001 | printk(KERN_EMERG "killing %s.\n",current->comm); | 1022 | printk(KERN_EMERG "killing %s.\n",current->comm); |
1002 | force_sig(SIGFPE,current); | 1023 | force_sig(SIGFPE,current); |
1003 | schedule(); | 1024 | schedule(); |
1004 | } | 1025 | } |
1005 | 1026 | ||
1006 | #endif /* CONFIG_MATH_EMULATION */ | 1027 | #endif /* CONFIG_MATH_EMULATION */ |
1007 | 1028 | ||
1008 | #ifdef CONFIG_X86_F00F_BUG | 1029 | #ifdef CONFIG_X86_F00F_BUG |
1009 | void __init trap_init_f00f_bug(void) | 1030 | void __init trap_init_f00f_bug(void) |
1010 | { | 1031 | { |
1011 | __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO); | 1032 | __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO); |
1012 | 1033 | ||
1013 | /* | 1034 | /* |
1014 | * Update the IDT descriptor and reload the IDT so that | 1035 | * Update the IDT descriptor and reload the IDT so that |
1015 | * it uses the read-only mapped virtual address. | 1036 | * it uses the read-only mapped virtual address. |
1016 | */ | 1037 | */ |
1017 | idt_descr.address = fix_to_virt(FIX_F00F_IDT); | 1038 | idt_descr.address = fix_to_virt(FIX_F00F_IDT); |
1018 | load_idt(&idt_descr); | 1039 | load_idt(&idt_descr); |
1019 | } | 1040 | } |
1020 | #endif | 1041 | #endif |
1021 | 1042 | ||
1022 | #define _set_gate(gate_addr,type,dpl,addr,seg) \ | 1043 | #define _set_gate(gate_addr,type,dpl,addr,seg) \ |
1023 | do { \ | 1044 | do { \ |
1024 | int __d0, __d1; \ | 1045 | int __d0, __d1; \ |
1025 | __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ | 1046 | __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ |
1026 | "movw %4,%%dx\n\t" \ | 1047 | "movw %4,%%dx\n\t" \ |
1027 | "movl %%eax,%0\n\t" \ | 1048 | "movl %%eax,%0\n\t" \ |
1028 | "movl %%edx,%1" \ | 1049 | "movl %%edx,%1" \ |
1029 | :"=m" (*((long *) (gate_addr))), \ | 1050 | :"=m" (*((long *) (gate_addr))), \ |
1030 | "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ | 1051 | "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ |
1031 | :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ | 1052 | :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ |
1032 | "3" ((char *) (addr)),"2" ((seg) << 16)); \ | 1053 | "3" ((char *) (addr)),"2" ((seg) << 16)); \ |
1033 | } while (0) | 1054 | } while (0) |
1034 | 1055 | ||
1035 | 1056 | ||
1036 | /* | 1057 | /* |
1037 | * This needs to use 'idt_table' rather than 'idt', and | 1058 | * This needs to use 'idt_table' rather than 'idt', and |
1038 | * thus use the _nonmapped_ version of the IDT, as the | 1059 | * thus use the _nonmapped_ version of the IDT, as the |
1039 | * Pentium F0 0F bugfix can have resulted in the mapped | 1060 | * Pentium F0 0F bugfix can have resulted in the mapped |
1040 | * IDT being write-protected. | 1061 | * IDT being write-protected. |
1041 | */ | 1062 | */ |
1042 | void set_intr_gate(unsigned int n, void *addr) | 1063 | void set_intr_gate(unsigned int n, void *addr) |
1043 | { | 1064 | { |
1044 | _set_gate(idt_table+n,14,0,addr,__KERNEL_CS); | 1065 | _set_gate(idt_table+n,14,0,addr,__KERNEL_CS); |
1045 | } | 1066 | } |
1046 | 1067 | ||
1047 | /* | 1068 | /* |
1048 | * This routine sets up an interrupt gate at directory privilege level 3. | 1069 | * This routine sets up an interrupt gate at directory privilege level 3. |
1049 | */ | 1070 | */ |
1050 | static inline void set_system_intr_gate(unsigned int n, void *addr) | 1071 | static inline void set_system_intr_gate(unsigned int n, void *addr) |
1051 | { | 1072 | { |
1052 | _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS); | 1073 | _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS); |
1053 | } | 1074 | } |
1054 | 1075 | ||
1055 | static void __init set_trap_gate(unsigned int n, void *addr) | 1076 | static void __init set_trap_gate(unsigned int n, void *addr) |
1056 | { | 1077 | { |
1057 | _set_gate(idt_table+n,15,0,addr,__KERNEL_CS); | 1078 | _set_gate(idt_table+n,15,0,addr,__KERNEL_CS); |
1058 | } | 1079 | } |
1059 | 1080 | ||
1060 | static void __init set_system_gate(unsigned int n, void *addr) | 1081 | static void __init set_system_gate(unsigned int n, void *addr) |
1061 | { | 1082 | { |
1062 | _set_gate(idt_table+n,15,3,addr,__KERNEL_CS); | 1083 | _set_gate(idt_table+n,15,3,addr,__KERNEL_CS); |
1063 | } | 1084 | } |
1064 | 1085 | ||
1065 | static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) | 1086 | static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) |
1066 | { | 1087 | { |
1067 | _set_gate(idt_table+n,5,0,0,(gdt_entry<<3)); | 1088 | _set_gate(idt_table+n,5,0,0,(gdt_entry<<3)); |
1068 | } | 1089 | } |
1069 | 1090 | ||
1070 | 1091 | ||
1071 | void __init trap_init(void) | 1092 | void __init trap_init(void) |
1072 | { | 1093 | { |
1073 | #ifdef CONFIG_EISA | 1094 | #ifdef CONFIG_EISA |
1074 | void __iomem *p = ioremap(0x0FFFD9, 4); | 1095 | void __iomem *p = ioremap(0x0FFFD9, 4); |
1075 | if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) { | 1096 | if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) { |
1076 | EISA_bus = 1; | 1097 | EISA_bus = 1; |
1077 | } | 1098 | } |
1078 | iounmap(p); | 1099 | iounmap(p); |
1079 | #endif | 1100 | #endif |
1080 | 1101 | ||
1081 | #ifdef CONFIG_X86_LOCAL_APIC | 1102 | #ifdef CONFIG_X86_LOCAL_APIC |
1082 | init_apic_mappings(); | 1103 | init_apic_mappings(); |
1083 | #endif | 1104 | #endif |
1084 | 1105 | ||
1085 | set_trap_gate(0,÷_error); | 1106 | set_trap_gate(0,÷_error); |
1086 | set_intr_gate(1,&debug); | 1107 | set_intr_gate(1,&debug); |
1087 | set_intr_gate(2,&nmi); | 1108 | set_intr_gate(2,&nmi); |
1088 | set_system_intr_gate(3, &int3); /* int3/4 can be called from all */ | 1109 | set_system_intr_gate(3, &int3); /* int3/4 can be called from all */ |
1089 | set_system_gate(4,&overflow); | 1110 | set_system_gate(4,&overflow); |
1090 | set_trap_gate(5,&bounds); | 1111 | set_trap_gate(5,&bounds); |
1091 | set_trap_gate(6,&invalid_op); | 1112 | set_trap_gate(6,&invalid_op); |
1092 | set_trap_gate(7,&device_not_available); | 1113 | set_trap_gate(7,&device_not_available); |
1093 | set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS); | 1114 | set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS); |
1094 | set_trap_gate(9,&coprocessor_segment_overrun); | 1115 | set_trap_gate(9,&coprocessor_segment_overrun); |
1095 | set_trap_gate(10,&invalid_TSS); | 1116 | set_trap_gate(10,&invalid_TSS); |
1096 | set_trap_gate(11,&segment_not_present); | 1117 | set_trap_gate(11,&segment_not_present); |
1097 | set_trap_gate(12,&stack_segment); | 1118 | set_trap_gate(12,&stack_segment); |
1098 | set_trap_gate(13,&general_protection); | 1119 | set_trap_gate(13,&general_protection); |
1099 | set_intr_gate(14,&page_fault); | 1120 | set_intr_gate(14,&page_fault); |
1100 | set_trap_gate(15,&spurious_interrupt_bug); | 1121 | set_trap_gate(15,&spurious_interrupt_bug); |
1101 | set_trap_gate(16,&coprocessor_error); | 1122 | set_trap_gate(16,&coprocessor_error); |
1102 | set_trap_gate(17,&alignment_check); | 1123 | set_trap_gate(17,&alignment_check); |
1103 | #ifdef CONFIG_X86_MCE | 1124 | #ifdef CONFIG_X86_MCE |
1104 | set_trap_gate(18,&machine_check); | 1125 | set_trap_gate(18,&machine_check); |
1105 | #endif | 1126 | #endif |
1106 | set_trap_gate(19,&simd_coprocessor_error); | 1127 | set_trap_gate(19,&simd_coprocessor_error); |
1107 | 1128 | ||
1108 | if (cpu_has_fxsr) { | 1129 | if (cpu_has_fxsr) { |
1109 | /* | 1130 | /* |
1110 | * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned. | 1131 | * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned. |
1111 | * Generates a compile-time "error: zero width for bit-field" if | 1132 | * Generates a compile-time "error: zero width for bit-field" if |
1112 | * the alignment is wrong. | 1133 | * the alignment is wrong. |
1113 | */ | 1134 | */ |
1114 | struct fxsrAlignAssert { | 1135 | struct fxsrAlignAssert { |
1115 | int _:!(offsetof(struct task_struct, | 1136 | int _:!(offsetof(struct task_struct, |
1116 | thread.i387.fxsave) & 15); | 1137 | thread.i387.fxsave) & 15); |
1117 | }; | 1138 | }; |
1118 | 1139 | ||
1119 | printk(KERN_INFO "Enabling fast FPU save and restore... "); | 1140 | printk(KERN_INFO "Enabling fast FPU save and restore... "); |
1120 | set_in_cr4(X86_CR4_OSFXSR); | 1141 | set_in_cr4(X86_CR4_OSFXSR); |
1121 | printk("done.\n"); | 1142 | printk("done.\n"); |
1122 | } | 1143 | } |
1123 | if (cpu_has_xmm) { | 1144 | if (cpu_has_xmm) { |
1124 | printk(KERN_INFO "Enabling unmasked SIMD FPU exception " | 1145 | printk(KERN_INFO "Enabling unmasked SIMD FPU exception " |
1125 | "support... "); | 1146 | "support... "); |
1126 | set_in_cr4(X86_CR4_OSXMMEXCPT); | 1147 | set_in_cr4(X86_CR4_OSXMMEXCPT); |
1127 | printk("done.\n"); | 1148 | printk("done.\n"); |
1128 | } | 1149 | } |
1129 | 1150 | ||
1130 | set_system_gate(SYSCALL_VECTOR,&system_call); | 1151 | set_system_gate(SYSCALL_VECTOR,&system_call); |
1131 | 1152 | ||
1132 | /* | 1153 | /* |
1133 | * Should be a barrier for any external CPU state. | 1154 | * Should be a barrier for any external CPU state. |
1134 | */ | 1155 | */ |
1135 | cpu_init(); | 1156 | cpu_init(); |
1136 | 1157 | ||
1137 | trap_init_hook(); | 1158 | trap_init_hook(); |
1138 | } | 1159 | } |
1139 | 1160 | ||
1140 | static int __init kstack_setup(char *s) | 1161 | static int __init kstack_setup(char *s) |
1141 | { | 1162 | { |