http://downloads.netgear.com/files/GPL/DM111PSP_v3.61d_GPL.tar.gz
[bcm963xx.git] / kernel / linux / arch / i386 / kernel / traps.c
1 /*
2  *  linux/arch/i386/traps.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *
6  *  Pentium III FXSR, SSE support
7  *      Gareth Hughes <gareth@valinux.com>, May 2000
8  */
9
10 /*
11  * 'Traps.c' handles hardware traps and faults after we have saved some
12  * state in 'asm.s'.
13  */
14 #include <linux/config.h>
15 #include <linux/sched.h>
16 #include <linux/kernel.h>
17 #include <linux/string.h>
18 #include <linux/errno.h>
19 #include <linux/timer.h>
20 #include <linux/mm.h>
21 #include <linux/init.h>
22 #include <linux/delay.h>
23 #include <linux/spinlock.h>
24 #include <linux/interrupt.h>
25 #include <linux/highmem.h>
26 #include <linux/kallsyms.h>
27 #include <linux/ptrace.h>
28 #include <linux/version.h>
29
30 #ifdef CONFIG_EISA
31 #include <linux/ioport.h>
32 #include <linux/eisa.h>
33 #endif
34
35 #ifdef CONFIG_MCA
36 #include <linux/mca.h>
37 #endif
38
39 #include <asm/processor.h>
40 #include <asm/system.h>
41 #include <asm/uaccess.h>
42 #include <asm/io.h>
43 #include <asm/atomic.h>
44 #include <asm/debugreg.h>
45 #include <asm/desc.h>
46 #include <asm/i387.h>
47 #include <asm/nmi.h>
48
49 #include <asm/smp.h>
50 #include <asm/arch_hooks.h>
51
52 #include <linux/irq.h>
53 #include <linux/module.h>
54
55 #include "mach_traps.h"
56
57 asmlinkage int system_call(void);
58 asmlinkage void lcall7(void);
59 asmlinkage void lcall27(void);
60
61 struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
62                 { 0, 0 }, { 0, 0 } };
63
64 /* Do we ignore FPU interrupts ? */
65 char ignore_fpu_irq = 0;
66
67 /*
68  * The IDT has to be page-aligned to simplify the Pentium
69  * F0 0F bug workaround.. We have a special link segment
70  * for this.
71  */
72 struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
73
74 asmlinkage void divide_error(void);
75 asmlinkage void debug(void);
76 asmlinkage void nmi(void);
77 asmlinkage void int3(void);
78 asmlinkage void overflow(void);
79 asmlinkage void bounds(void);
80 asmlinkage void invalid_op(void);
81 asmlinkage void device_not_available(void);
82 asmlinkage void coprocessor_segment_overrun(void);
83 asmlinkage void invalid_TSS(void);
84 asmlinkage void segment_not_present(void);
85 asmlinkage void stack_segment(void);
86 asmlinkage void general_protection(void);
87 asmlinkage void page_fault(void);
88 asmlinkage void coprocessor_error(void);
89 asmlinkage void simd_coprocessor_error(void);
90 asmlinkage void alignment_check(void);
91 asmlinkage void spurious_interrupt_bug(void);
92 asmlinkage void machine_check(void);
93
94 static int kstack_depth_to_print = 24;
95
96 static int valid_stack_ptr(struct task_struct *task, void *p)
97 {
98         if (p <= (void *)task->thread_info)
99                 return 0;
100         if (kstack_end(p))
101                 return 0;
102         return 1;
103 }
104
105 #ifdef CONFIG_FRAME_POINTER
106 static void print_context_stack(struct task_struct *task, unsigned long *stack,
107                          unsigned long ebp)
108 {
109         unsigned long addr;
110
111         while (valid_stack_ptr(task, (void *)ebp)) {
112                 addr = *(unsigned long *)(ebp + 4);
113                 printk(" [<%08lx>] ", addr);
114                 print_symbol("%s", addr);
115                 printk("\n");
116                 ebp = *(unsigned long *)ebp;
117         }
118 }
119 #else
120 static void print_context_stack(struct task_struct *task, unsigned long *stack,
121                          unsigned long ebp)
122 {
123         unsigned long addr;
124
125         while (!kstack_end(stack)) {
126                 addr = *stack++;
127                 if (__kernel_text_address(addr)) {
128                         printk(" [<%08lx>]", addr);
129                         print_symbol(" %s", addr);
130                         printk("\n");
131                 }
132         }
133 }
134 #endif
135
136 void show_trace(struct task_struct *task, unsigned long * stack)
137 {
138         unsigned long ebp;
139
140         if (!task)
141                 task = current;
142
143         if (!valid_stack_ptr(task, stack)) {
144                 printk("Stack pointer is garbage, not printing trace\n");
145                 return;
146         }
147
148         if (task == current) {
149                 /* Grab ebp right from our regs */
150                 asm ("movl %%ebp, %0" : "=r" (ebp) : );
151         } else {
152                 /* ebp is the last reg pushed by switch_to */
153                 ebp = *(unsigned long *) task->thread.esp;
154         }
155
156         while (1) {
157                 struct thread_info *context;
158                 context = (struct thread_info *)
159                         ((unsigned long)stack & (~(THREAD_SIZE - 1)));
160                 print_context_stack(task, stack, ebp);
161                 stack = (unsigned long*)context->previous_esp;
162                 if (!stack)
163                         break;
164                 printk(" =======================\n");
165         }
166 }
167
168 void show_stack(struct task_struct *task, unsigned long *esp)
169 {
170         unsigned long *stack;
171         int i;
172
173         if (esp == NULL) {
174                 if (task)
175                         esp = (unsigned long*)task->thread.esp;
176                 else
177                         esp = (unsigned long *)&esp;
178         }
179
180         stack = esp;
181         for(i = 0; i < kstack_depth_to_print; i++) {
182                 if (kstack_end(stack))
183                         break;
184                 if (i && ((i % 8) == 0))
185                         printk("\n       ");
186                 printk("%08lx ", *stack++);
187         }
188         printk("\nCall Trace:\n");
189         show_trace(task, esp);
190 }
191
192 /*
193  * The architecture-independent dump_stack generator
194  */
195 void dump_stack(void)
196 {
197         unsigned long stack;
198
199         show_trace(current, &stack);
200 }
201
202 EXPORT_SYMBOL(dump_stack);
203
204 void show_registers(struct pt_regs *regs)
205 {
206         int i;
207         int in_kernel = 1;
208         unsigned long esp;
209         unsigned short ss;
210
211         esp = (unsigned long) (&regs->esp);
212         ss = __KERNEL_DS;
213         if (regs->xcs & 3) {
214                 in_kernel = 0;
215                 esp = regs->esp;
216                 ss = regs->xss & 0xffff;
217         }
218         print_modules();
219         printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx"
220                         "   (%s) \n",
221                 smp_processor_id(), 0xffff & regs->xcs, regs->eip,
222                 print_tainted(), regs->eflags, UTS_RELEASE);
223         print_symbol("EIP is at %s\n", regs->eip);
224         printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
225                 regs->eax, regs->ebx, regs->ecx, regs->edx);
226         printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
227                 regs->esi, regs->edi, regs->ebp, esp);
228         printk("ds: %04x   es: %04x   ss: %04x\n",
229                 regs->xds & 0xffff, regs->xes & 0xffff, ss);
230         printk("Process %s (pid: %d, threadinfo=%p task=%p)",
231                 current->comm, current->pid, current_thread_info(), current);
232         /*
233          * When in-kernel, we also print out the stack and code at the
234          * time of the fault..
235          */
236         if (in_kernel) {
237
238                 printk("\nStack: ");
239                 show_stack(NULL, (unsigned long*)esp);
240
241                 printk("Code: ");
242                 if(regs->eip < PAGE_OFFSET)
243                         goto bad;
244
245                 for(i=0;i<20;i++)
246                 {
247                         unsigned char c;
248                         if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
249 bad:
250                                 printk(" Bad EIP value.");
251                                 break;
252                         }
253                         printk("%02x ", c);
254                 }
255         }
256         printk("\n");
257 }       
258
259 static void handle_BUG(struct pt_regs *regs)
260 {
261         unsigned short ud2;
262         unsigned short line;
263         char *file;
264         char c;
265         unsigned long eip;
266
267         if (regs->xcs & 3)
268                 goto no_bug;            /* Not in kernel */
269
270         eip = regs->eip;
271
272         if (eip < PAGE_OFFSET)
273                 goto no_bug;
274         if (__get_user(ud2, (unsigned short *)eip))
275                 goto no_bug;
276         if (ud2 != 0x0b0f)
277                 goto no_bug;
278         if (__get_user(line, (unsigned short *)(eip + 2)))
279                 goto bug;
280         if (__get_user(file, (char **)(eip + 4)) ||
281                 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
282                 file = "<bad filename>";
283
284         printk("------------[ cut here ]------------\n");
285         printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line);
286
287 no_bug:
288         return;
289
290         /* Here we know it was a BUG but file-n-line is unavailable */
291 bug:
292         printk("Kernel BUG\n");
293 }
294
295 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
296
297 void die(const char * str, struct pt_regs * regs, long err)
298 {
299         static int die_counter;
300         int nl = 0;
301
302         console_verbose();
303         spin_lock_irq(&die_lock);
304         bust_spinlocks(1);
305         handle_BUG(regs);
306         printk(KERN_ALERT "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
307 #ifdef CONFIG_PREEMPT
308         printk("PREEMPT ");
309         nl = 1;
310 #endif
311 #ifdef CONFIG_SMP
312         printk("SMP ");
313         nl = 1;
314 #endif
315 #ifdef CONFIG_DEBUG_PAGEALLOC
316         printk("DEBUG_PAGEALLOC");
317         nl = 1;
318 #endif
319         if (nl)
320                 printk("\n");
321         show_registers(regs);
322         bust_spinlocks(0);
323         spin_unlock_irq(&die_lock);
324         if (in_interrupt())
325                 panic("Fatal exception in interrupt");
326
327         if (panic_on_oops) {
328                 printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
329                 set_current_state(TASK_UNINTERRUPTIBLE);
330                 schedule_timeout(5 * HZ);
331                 panic("Fatal exception");
332         }
333         do_exit(SIGSEGV);
334 }
335
336 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
337 {
338         if (!(regs->eflags & VM_MASK) && !(3 & regs->xcs))
339                 die(str, regs, err);
340 }
341
342 static inline unsigned long get_cr2(void)
343 {
344         unsigned long address;
345
346         /* get the address */
347         __asm__("movl %%cr2,%0":"=r" (address));
348         return address;
349 }
350
351 static inline void do_trap(int trapnr, int signr, char *str, int vm86,
352                            struct pt_regs * regs, long error_code, siginfo_t *info)
353 {
354         if (regs->eflags & VM_MASK) {
355                 if (vm86)
356                         goto vm86_trap;
357                 goto trap_signal;
358         }
359
360         if (!(regs->xcs & 3))
361                 goto kernel_trap;
362
363         trap_signal: {
364                 struct task_struct *tsk = current;
365                 tsk->thread.error_code = error_code;
366                 tsk->thread.trap_no = trapnr;
367                 if (info)
368                         force_sig_info(signr, info, tsk);
369                 else
370                         force_sig(signr, tsk);
371                 return;
372         }
373
374         kernel_trap: {
375                 if (!fixup_exception(regs))
376                         die(str, regs, error_code);
377                 return;
378         }
379
380         vm86_trap: {
381                 int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr);
382                 if (ret) goto trap_signal;
383                 return;
384         }
385 }
386
387 #define DO_ERROR(trapnr, signr, str, name) \
388 asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
389 { \
390         do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
391 }
392
393 #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
394 asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
395 { \
396         siginfo_t info; \
397         info.si_signo = signr; \
398         info.si_errno = 0; \
399         info.si_code = sicode; \
400         info.si_addr = (void __user *)siaddr; \
401         do_trap(trapnr, signr, str, 0, regs, error_code, &info); \
402 }
403
404 #define DO_VM86_ERROR(trapnr, signr, str, name) \
405 asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
406 { \
407         do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
408 }
409
410 #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
411 asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
412 { \
413         siginfo_t info; \
414         info.si_signo = signr; \
415         info.si_errno = 0; \
416         info.si_code = sicode; \
417         info.si_addr = (void __user *)siaddr; \
418         do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
419 }
420
421 DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->eip)
422 DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
423 DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
424 DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
425 DO_ERROR_INFO( 6, SIGILL,  "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
426 DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
427 DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
428 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
429 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
430 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2())
431
432 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
433 {
434         if (regs->eflags & X86_EFLAGS_IF)
435                 local_irq_enable();
436  
437         if (regs->eflags & VM_MASK)
438                 goto gp_in_vm86;
439
440         if (!(regs->xcs & 3))
441                 goto gp_in_kernel;
442
443         current->thread.error_code = error_code;
444         current->thread.trap_no = 13;
445         force_sig(SIGSEGV, current);
446         return;
447
448 gp_in_vm86:
449         local_irq_enable();
450         handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
451         return;
452
453 gp_in_kernel:
454         if (!fixup_exception(regs))
455                 die("general protection fault", regs, error_code);
456 }
457
458 static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
459 {
460         printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
461         printk("You probably have a hardware problem with your RAM chips\n");
462
463         /* Clear and disable the memory parity error line. */
464         clear_mem_error(reason);
465 }
466
467 static void io_check_error(unsigned char reason, struct pt_regs * regs)
468 {
469         unsigned long i;
470
471         printk("NMI: IOCK error (debug interrupt?)\n");
472         show_registers(regs);
473
474         /* Re-enable the IOCK line, wait for a few seconds */
475         reason = (reason & 0xf) | 8;
476         outb(reason, 0x61);
477         i = 2000;
478         while (--i) udelay(1000);
479         reason &= ~8;
480         outb(reason, 0x61);
481 }
482
483 static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
484 {
485 #ifdef CONFIG_MCA
486         /* Might actually be able to figure out what the guilty party
487         * is. */
488         if( MCA_bus ) {
489                 mca_handle_nmi();
490                 return;
491         }
492 #endif
493         printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
494                 reason, smp_processor_id());
495         printk("Dazed and confused, but trying to continue\n");
496         printk("Do you have a strange power saving mode enabled?\n");
497 }
498
499 static void default_do_nmi(struct pt_regs * regs)
500 {
501         unsigned char reason = get_nmi_reason();
502  
503         if (!(reason & 0xc0)) {
504 #ifdef CONFIG_X86_LOCAL_APIC
505                 /*
506                  * Ok, so this is none of the documented NMI sources,
507                  * so it must be the NMI watchdog.
508                  */
509                 if (nmi_watchdog) {
510                         nmi_watchdog_tick(regs);
511                         return;
512                 }
513 #endif
514                 unknown_nmi_error(reason, regs);
515                 return;
516         }
517         if (reason & 0x80)
518                 mem_parity_error(reason, regs);
519         if (reason & 0x40)
520                 io_check_error(reason, regs);
521         /*
522          * Reassert NMI in case it became active meanwhile
523          * as it's edge-triggered.
524          */
525         reassert_nmi();
526 }
527
528 static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
529 {
530         return 0;
531 }
532  
533 static nmi_callback_t nmi_callback = dummy_nmi_callback;
534  
535 asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
536 {
537         int cpu;
538
539         nmi_enter();
540
541         cpu = smp_processor_id();
542         ++nmi_count(cpu);
543
544         if (!nmi_callback(regs, cpu))
545                 default_do_nmi(regs);
546
547         nmi_exit();
548 }
549
550 void set_nmi_callback(nmi_callback_t callback)
551 {
552         nmi_callback = callback;
553 }
554
555 void unset_nmi_callback(void)
556 {
557         nmi_callback = dummy_nmi_callback;
558 }
559
560 /*
561  * Our handling of the processor debug registers is non-trivial.
562  * We do not clear them on entry and exit from the kernel. Therefore
563  * it is possible to get a watchpoint trap here from inside the kernel.
564  * However, the code in ./ptrace.c has ensured that the user can
565  * only set watchpoints on userspace addresses. Therefore the in-kernel
566  * watchpoint trap can only occur in code which is reading/writing
567  * from user space. Such code must not hold kernel locks (since it
568  * can equally take a page fault), therefore it is safe to call
569  * force_sig_info even though that claims and releases locks.
570  * 
571  * Code in ./signal.c ensures that the debug control register
572  * is restored before we deliver any signal, and therefore that
573  * user code runs with the correct debug control register even though
574  * we clear it here.
575  *
576  * Being careful here means that we don't have to be as careful in a
577  * lot of more complicated places (task switching can be a bit lazy
578  * about restoring all the debug state, and ptrace doesn't have to
579  * find every occurrence of the TF bit that could be saved away even
580  * by user code)
581  */
582 asmlinkage void do_debug(struct pt_regs * regs, long error_code)
583 {
584         unsigned int condition;
585         struct task_struct *tsk = current;
586         siginfo_t info;
587
588         __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
589
590         /* It's safe to allow irq's after DR6 has been saved */
591         if (regs->eflags & X86_EFLAGS_IF)
592                 local_irq_enable();
593
594         /* Mask out spurious debug traps due to lazy DR7 setting */
595         if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
596                 if (!tsk->thread.debugreg[7])
597                         goto clear_dr7;
598         }
599
600         if (regs->eflags & VM_MASK)
601                 goto debug_vm86;
602
603         /* Save debug status register where ptrace can see it */
604         tsk->thread.debugreg[6] = condition;
605
606         /* Mask out spurious TF errors due to lazy TF clearing */
607         if (condition & DR_STEP) {
608                 /*
609                  * The TF error should be masked out only if the current
610                  * process is not traced and if the TRAP flag has been set
611                  * previously by a tracing process (condition detected by
612                  * the PT_DTRACE flag); remember that the i386 TRAP flag
613                  * can be modified by the process itself in user mode,
614                  * allowing programs to debug themselves without the ptrace()
615                  * interface.
616                  */
617                 if ((regs->xcs & 3) == 0)
618                         goto clear_TF_reenable;
619                 if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
620                         goto clear_TF;
621         }
622
623         /* Ok, finally something we can handle */
624         tsk->thread.trap_no = 1;
625         tsk->thread.error_code = error_code;
626         info.si_signo = SIGTRAP;
627         info.si_errno = 0;
628         info.si_code = TRAP_BRKPT;
629         
630         /* If this is a kernel mode trap, save the user PC on entry to 
631          * the kernel, that's what the debugger can make sense of.
632          */
633         info.si_addr = ((regs->xcs & 3) == 0) ? (void __user *)tsk->thread.eip
634                                               : (void __user *)regs->eip;
635         force_sig_info(SIGTRAP, &info, tsk);
636
637         /* Disable additional traps. They'll be re-enabled when
638          * the signal is delivered.
639          */
640 clear_dr7:
641         __asm__("movl %0,%%db7"
642                 : /* no output */
643                 : "r" (0));
644         return;
645
646 debug_vm86:
647         handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
648         return;
649
650 clear_TF_reenable:
651         set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
652 clear_TF:
653         regs->eflags &= ~TF_MASK;
654         return;
655 }
656
657 /*
658  * Note that we play around with the 'TS' bit in an attempt to get
659  * the correct behaviour even in the presence of the asynchronous
660  * IRQ13 behaviour
661  */
662 void math_error(void __user *eip)
663 {
664         struct task_struct * task;
665         siginfo_t info;
666         unsigned short cwd, swd;
667
668         /*
669          * Save the info for the exception handler and clear the error.
670          */
671         task = current;
672         save_init_fpu(task);
673         task->thread.trap_no = 16;
674         task->thread.error_code = 0;
675         info.si_signo = SIGFPE;
676         info.si_errno = 0;
677         info.si_code = __SI_FAULT;
678         info.si_addr = eip;
679         /*
680          * (~cwd & swd) will mask out exceptions that are not set to unmasked
681          * status.  0x3f is the exception bits in these regs, 0x200 is the
682          * C1 reg you need in case of a stack fault, 0x040 is the stack
683          * fault bit.  We should only be taking one exception at a time,
684          * so if this combination doesn't produce any single exception,
685          * then we have a bad program that isn't syncronizing its FPU usage
686          * and it will suffer the consequences since we won't be able to
687          * fully reproduce the context of the exception
688          */
689         cwd = get_fpu_cwd(task);
690         swd = get_fpu_swd(task);
691         switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
692                 case 0x000:
693                 default:
694                         break;
695                 case 0x001: /* Invalid Op */
696                 case 0x041: /* Stack Fault */
697                 case 0x241: /* Stack Fault | Direction */
698                         info.si_code = FPE_FLTINV;
699                         /* Should we clear the SF or let user space do it ???? */
700                         break;
701                 case 0x002: /* Denormalize */
702                 case 0x010: /* Underflow */
703                         info.si_code = FPE_FLTUND;
704                         break;
705                 case 0x004: /* Zero Divide */
706                         info.si_code = FPE_FLTDIV;
707                         break;
708                 case 0x008: /* Overflow */
709                         info.si_code = FPE_FLTOVF;
710                         break;
711                 case 0x020: /* Precision */
712                         info.si_code = FPE_FLTRES;
713                         break;
714         }
715         force_sig_info(SIGFPE, &info, task);
716 }
717
718 asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
719 {
720         ignore_fpu_irq = 1;
721         math_error((void __user *)regs->eip);
722 }
723
724 void simd_math_error(void __user *eip)
725 {
726         struct task_struct * task;
727         siginfo_t info;
728         unsigned short mxcsr;
729
730         /*
731          * Save the info for the exception handler and clear the error.
732          */
733         task = current;
734         save_init_fpu(task);
735         task->thread.trap_no = 19;
736         task->thread.error_code = 0;
737         info.si_signo = SIGFPE;
738         info.si_errno = 0;
739         info.si_code = __SI_FAULT;
740         info.si_addr = eip;
741         /*
742          * The SIMD FPU exceptions are handled a little differently, as there
743          * is only a single status/control register.  Thus, to determine which
744          * unmasked exception was caught we must mask the exception mask bits
745          * at 0x1f80, and then use these to mask the exception bits at 0x3f.
746          */
747         mxcsr = get_fpu_mxcsr(task);
748         switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
749                 case 0x000:
750                 default:
751                         break;
752                 case 0x001: /* Invalid Op */
753                         info.si_code = FPE_FLTINV;
754                         break;
755                 case 0x002: /* Denormalize */
756                 case 0x010: /* Underflow */
757                         info.si_code = FPE_FLTUND;
758                         break;
759                 case 0x004: /* Zero Divide */
760                         info.si_code = FPE_FLTDIV;
761                         break;
762                 case 0x008: /* Overflow */
763                         info.si_code = FPE_FLTOVF;
764                         break;
765                 case 0x020: /* Precision */
766                         info.si_code = FPE_FLTRES;
767                         break;
768         }
769         force_sig_info(SIGFPE, &info, task);
770 }
771
772 asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs,
773                                           long error_code)
774 {
775         if (cpu_has_xmm) {
776                 /* Handle SIMD FPU exceptions on PIII+ processors. */
777                 ignore_fpu_irq = 1;
778                 simd_math_error((void __user *)regs->eip);
779         } else {
780                 /*
781                  * Handle strange cache flush from user space exception
782                  * in all other cases.  This is undocumented behaviour.
783                  */
784                 if (regs->eflags & VM_MASK) {
785                         handle_vm86_fault((struct kernel_vm86_regs *)regs,
786                                           error_code);
787                         return;
788                 }
789                 die_if_kernel("cache flush denied", regs, error_code);
790                 current->thread.trap_no = 19;
791                 current->thread.error_code = error_code;
792                 force_sig(SIGSEGV, current);
793         }
794 }
795
796 asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs,
797                                           long error_code)
798 {
799 #if 0
800         /* No need to warn about this any longer. */
801         printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
802 #endif
803 }
804
805 /*
806  *  'math_state_restore()' saves the current math information in the
807  * old math state array, and gets the new ones from the current task
808  *
809  * Careful.. There are problems with IBM-designed IRQ13 behaviour.
810  * Don't touch unless you *really* know how it works.
811  *
812  * Must be called with kernel preemption disabled (in this case,
813  * local interrupts are disabled at the call-site in entry.S).
814  */
815 asmlinkage void math_state_restore(struct pt_regs regs)
816 {
817         struct thread_info *thread = current_thread_info();
818         struct task_struct *tsk = thread->task;
819
820         clts();         /* Allow maths ops (or we recurse) */
821         if (!tsk->used_math)
822                 init_fpu(tsk);
823         restore_fpu(tsk);
824         thread->status |= TS_USEDFPU;   /* So we fnsave on switch_to() */
825 }
826
827 #ifndef CONFIG_MATH_EMULATION
828
829 asmlinkage void math_emulate(long arg)
830 {
831         printk("math-emulation not enabled and no coprocessor found.\n");
832         printk("killing %s.\n",current->comm);
833         force_sig(SIGFPE,current);
834         schedule();
835 }
836
837 #endif /* CONFIG_MATH_EMULATION */
838
839 #ifdef CONFIG_X86_F00F_BUG
840 void __init trap_init_f00f_bug(void)
841 {
842         __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
843
844         /*
845          * Update the IDT descriptor and reload the IDT so that
846          * it uses the read-only mapped virtual address.
847          */
848         idt_descr.address = fix_to_virt(FIX_F00F_IDT);
849         __asm__ __volatile__("lidt %0" : : "m" (idt_descr));
850 }
851 #endif
852
853 #define _set_gate(gate_addr,type,dpl,addr,seg) \
854 do { \
855   int __d0, __d1; \
856   __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
857         "movw %4,%%dx\n\t" \
858         "movl %%eax,%0\n\t" \
859         "movl %%edx,%1" \
860         :"=m" (*((long *) (gate_addr))), \
861          "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
862         :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
863          "3" ((char *) (addr)),"2" ((seg) << 16)); \
864 } while (0)
865
866
867 /*
868  * This needs to use 'idt_table' rather than 'idt', and
869  * thus use the _nonmapped_ version of the IDT, as the
870  * Pentium F0 0F bugfix can have resulted in the mapped
871  * IDT being write-protected.
872  */
873 void set_intr_gate(unsigned int n, void *addr)
874 {
875         _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
876 }
877
878 static void __init set_trap_gate(unsigned int n, void *addr)
879 {
880         _set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
881 }
882
883 static void __init set_system_gate(unsigned int n, void *addr)
884 {
885         _set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
886 }
887
888 static void __init set_call_gate(void *a, void *addr)
889 {
890         _set_gate(a,12,3,addr,__KERNEL_CS);
891 }
892
893 static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
894 {
895         _set_gate(idt_table+n,5,0,0,(gdt_entry<<3));
896 }
897
898
899 void __init trap_init(void)
900 {
901 #ifdef CONFIG_EISA
902         if (isa_readl(0x0FFFD9) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
903                 EISA_bus = 1;
904         }
905 #endif
906
907 #ifdef CONFIG_X86_LOCAL_APIC
908         init_apic_mappings();
909 #endif
910
911         set_trap_gate(0,&divide_error);
912         set_intr_gate(1,&debug);
913         set_intr_gate(2,&nmi);
914         set_system_gate(3,&int3);       /* int3-5 can be called from all */
915         set_system_gate(4,&overflow);
916         set_system_gate(5,&bounds);
917         set_trap_gate(6,&invalid_op);
918         set_trap_gate(7,&device_not_available);
919         set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS);
920         set_trap_gate(9,&coprocessor_segment_overrun);
921         set_trap_gate(10,&invalid_TSS);
922         set_trap_gate(11,&segment_not_present);
923         set_trap_gate(12,&stack_segment);
924         set_trap_gate(13,&general_protection);
925         set_intr_gate(14,&page_fault);
926         set_trap_gate(15,&spurious_interrupt_bug);
927         set_trap_gate(16,&coprocessor_error);
928         set_trap_gate(17,&alignment_check);
929 #ifdef CONFIG_X86_MCE
930         set_trap_gate(18,&machine_check);
931 #endif
932         set_trap_gate(19,&simd_coprocessor_error);
933
934         set_system_gate(SYSCALL_VECTOR,&system_call);
935
936         /*
937          * default LDT is a single-entry callgate to lcall7 for iBCS
938          * and a callgate to lcall27 for Solaris/x86 binaries
939          */
940         set_call_gate(&default_ldt[0],lcall7);
941         set_call_gate(&default_ldt[4],lcall27);
942
943         /*
944          * Should be a barrier for any external CPU state.
945          */
946         cpu_init();
947
948         trap_init_hook();
949 }