PageRenderTime 85ms CodeModel.GetById 12ms app.highlight 65ms RepoModel.GetById 2ms app.codeStats 0ms

/arch/x86_64/kernel/traps.c

https://bitbucket.org/evzijst/gittest
C | 948 lines | 733 code | 106 blank | 109 comment | 114 complexity | c2753cdd302fe2b646fab79f63e99196 MD5 | raw file
  1/*
  2 *  linux/arch/x86-64/traps.c
  3 *
  4 *  Copyright (C) 1991, 1992  Linus Torvalds
  5 *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
  6 *
  7 *  Pentium III FXSR, SSE support
  8 *	Gareth Hughes <gareth@valinux.com>, May 2000
  9 *
 10 *  $Id: traps.c,v 1.36 2002/03/24 11:09:10 ak Exp $
 11 */
 12
 13/*
 14 * 'Traps.c' handles hardware traps and faults after we have saved some
 15 * state in 'entry.S'.
 16 */
 17#include <linux/config.h>
 18#include <linux/sched.h>
 19#include <linux/kernel.h>
 20#include <linux/string.h>
 21#include <linux/errno.h>
 22#include <linux/ptrace.h>
 23#include <linux/timer.h>
 24#include <linux/mm.h>
 25#include <linux/init.h>
 26#include <linux/delay.h>
 27#include <linux/spinlock.h>
 28#include <linux/interrupt.h>
 29#include <linux/module.h>
 30#include <linux/moduleparam.h>
 31
 32#include <asm/system.h>
 33#include <asm/uaccess.h>
 34#include <asm/io.h>
 35#include <asm/atomic.h>
 36#include <asm/debugreg.h>
 37#include <asm/desc.h>
 38#include <asm/i387.h>
 39#include <asm/kdebug.h>
 40#include <asm/processor.h>
 41
 42#include <asm/smp.h>
 43#include <asm/pgalloc.h>
 44#include <asm/pda.h>
 45#include <asm/proto.h>
 46#include <asm/nmi.h>
 47
 48#include <linux/irq.h>
 49
 50
 51extern struct gate_struct idt_table[256]; 
 52
 53asmlinkage void divide_error(void);
 54asmlinkage void debug(void);
 55asmlinkage void nmi(void);
 56asmlinkage void int3(void);
 57asmlinkage void overflow(void);
 58asmlinkage void bounds(void);
 59asmlinkage void invalid_op(void);
 60asmlinkage void device_not_available(void);
 61asmlinkage void double_fault(void);
 62asmlinkage void coprocessor_segment_overrun(void);
 63asmlinkage void invalid_TSS(void);
 64asmlinkage void segment_not_present(void);
 65asmlinkage void stack_segment(void);
 66asmlinkage void general_protection(void);
 67asmlinkage void page_fault(void);
 68asmlinkage void coprocessor_error(void);
 69asmlinkage void simd_coprocessor_error(void);
 70asmlinkage void reserved(void);
 71asmlinkage void alignment_check(void);
 72asmlinkage void machine_check(void);
 73asmlinkage void spurious_interrupt_bug(void);
 74asmlinkage void call_debug(void);
 75
 76struct notifier_block *die_chain;
 77static DEFINE_SPINLOCK(die_notifier_lock);
 78
 79int register_die_notifier(struct notifier_block *nb)
 80{
 81	int err = 0;
 82	unsigned long flags;
 83	spin_lock_irqsave(&die_notifier_lock, flags);
 84	err = notifier_chain_register(&die_chain, nb);
 85	spin_unlock_irqrestore(&die_notifier_lock, flags);
 86	return err;
 87}
 88
 89static inline void conditional_sti(struct pt_regs *regs)
 90{
 91	if (regs->eflags & X86_EFLAGS_IF)
 92		local_irq_enable();
 93}
 94
 95static int kstack_depth_to_print = 10;
 96
 97#ifdef CONFIG_KALLSYMS
 98#include <linux/kallsyms.h> 
 99int printk_address(unsigned long address)
100{ 
101	unsigned long offset = 0, symsize;
102	const char *symname;
103	char *modname;
104	char *delim = ":"; 
105	char namebuf[128];
106
107	symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); 
108	if (!symname) 
109		return printk("[<%016lx>]", address);
110	if (!modname) 
111		modname = delim = ""; 		
112        return printk("<%016lx>{%s%s%s%s%+ld}",
113		      address,delim,modname,delim,symname,offset); 
114} 
115#else
116int printk_address(unsigned long address)
117{ 
118	return printk("[<%016lx>]", address);
119} 
120#endif
121
122unsigned long *in_exception_stack(int cpu, unsigned long stack) 
123{ 
124	int k;
125	for (k = 0; k < N_EXCEPTION_STACKS; k++) {
126		struct tss_struct *tss = &per_cpu(init_tss, cpu);
127		unsigned long start = tss->ist[k] - EXCEPTION_STKSZ;
128
129		if (stack >= start && stack < tss->ist[k])
130			return (unsigned long *)tss->ist[k];
131	}
132	return NULL;
133} 
134
135/*
136 * x86-64 can have upto three kernel stacks: 
137 * process stack
138 * interrupt stack
139 * severe exception (double fault, nmi, stack fault) hardware stack
140 * Check and process them in order.
141 */
142
143void show_trace(unsigned long *stack)
144{
145	unsigned long addr;
146	unsigned long *irqstack, *irqstack_end, *estack_end;
147	const int cpu = safe_smp_processor_id();
148	int i;
149
150	printk("\nCall Trace:");
151	i = 0; 
152	
153	estack_end = in_exception_stack(cpu, (unsigned long)stack); 
154	if (estack_end) { 
155		while (stack < estack_end) { 
156			addr = *stack++; 
157			if (__kernel_text_address(addr)) {
158				i += printk_address(addr);
159				i += printk(" "); 
160				if (i > 50) {
161					printk("\n"); 
162					i = 0;
163				}
164			}
165		}
166		i += printk(" <EOE> "); 
167		i += 7;
168		stack = (unsigned long *) estack_end[-2]; 
169	}  
170
171	irqstack_end = (unsigned long *) (cpu_pda[cpu].irqstackptr);
172	irqstack = (unsigned long *) (cpu_pda[cpu].irqstackptr - IRQSTACKSIZE + 64);
173
174	if (stack >= irqstack && stack < irqstack_end) {
175		printk("<IRQ> ");  
176		while (stack < irqstack_end) {
177			addr = *stack++;
178			/*
179			 * If the address is either in the text segment of the
180			 * kernel, or in the region which contains vmalloc'ed
181			 * memory, it *may* be the address of a calling
182			 * routine; if so, print it so that someone tracing
183			 * down the cause of the crash will be able to figure
184			 * out the call path that was taken.
185			 */
186			 if (__kernel_text_address(addr)) {
187				 i += printk_address(addr);
188				 i += printk(" "); 
189				 if (i > 50) { 
190					printk("\n       ");
191					 i = 0;
192				 } 
193			}
194		} 
195		stack = (unsigned long *) (irqstack_end[-1]);
196		printk(" <EOI> ");
197		i += 7;
198	} 
199
200	while (((long) stack & (THREAD_SIZE-1)) != 0) {
201		addr = *stack++;
202		if (__kernel_text_address(addr)) {
203			i += printk_address(addr);
204			i += printk(" "); 
205			if (i > 50) { 
206				printk("\n       ");
207					 i = 0;
208			} 
209		}
210	}
211	printk("\n");
212}
213
214void show_stack(struct task_struct *tsk, unsigned long * rsp)
215{
216	unsigned long *stack;
217	int i;
218	const int cpu = safe_smp_processor_id();
219	unsigned long *irqstack_end = (unsigned long *) (cpu_pda[cpu].irqstackptr);
220	unsigned long *irqstack = (unsigned long *) (cpu_pda[cpu].irqstackptr - IRQSTACKSIZE);    
221
222	// debugging aid: "show_stack(NULL, NULL);" prints the
223	// back trace for this cpu.
224
225	if (rsp == NULL) {
226		if (tsk)
227			rsp = (unsigned long *)tsk->thread.rsp;
228		else
229			rsp = (unsigned long *)&rsp;
230	}
231
232	stack = rsp;
233	for(i=0; i < kstack_depth_to_print; i++) {
234		if (stack >= irqstack && stack <= irqstack_end) {
235			if (stack == irqstack_end) {
236				stack = (unsigned long *) (irqstack_end[-1]);
237				printk(" <EOI> ");
238			}
239		} else {
240		if (((long) stack & (THREAD_SIZE-1)) == 0)
241			break;
242		}
243		if (i && ((i % 4) == 0))
244			printk("\n       ");
245		printk("%016lx ", *stack++);
246	}
247	show_trace((unsigned long *)rsp);
248}
249
250/*
251 * The architecture-independent dump_stack generator
252 */
253void dump_stack(void)
254{
255	unsigned long dummy;
256	show_trace(&dummy);
257}
258
259EXPORT_SYMBOL(dump_stack);
260
261void show_registers(struct pt_regs *regs)
262{
263	int i;
264	int in_kernel = (regs->cs & 3) == 0;
265	unsigned long rsp;
266	const int cpu = safe_smp_processor_id(); 
267	struct task_struct *cur = cpu_pda[cpu].pcurrent; 
268
269		rsp = regs->rsp;
270
271	printk("CPU %d ", cpu);
272	__show_regs(regs);
273	printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
274		cur->comm, cur->pid, cur->thread_info, cur);
275
276	/*
277	 * When in-kernel, we also print out the stack and code at the
278	 * time of the fault..
279	 */
280	if (in_kernel) {
281
282		printk("Stack: ");
283		show_stack(NULL, (unsigned long*)rsp);
284
285		printk("\nCode: ");
286		if(regs->rip < PAGE_OFFSET)
287			goto bad;
288
289		for(i=0;i<20;i++)
290		{
291			unsigned char c;
292			if(__get_user(c, &((unsigned char*)regs->rip)[i])) {
293bad:
294				printk(" Bad RIP value.");
295				break;
296			}
297			printk("%02x ", c);
298		}
299	}
300	printk("\n");
301}	
302
303void handle_BUG(struct pt_regs *regs)
304{ 
305	struct bug_frame f;
306	char tmp;
307
308	if (regs->cs & 3)
309		return; 
310	if (__copy_from_user(&f, (struct bug_frame *) regs->rip, 
311			     sizeof(struct bug_frame)))
312		return; 
313	if ((unsigned long)f.filename < __PAGE_OFFSET || 
314	    f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) 
315		return;
316	if (__get_user(tmp, f.filename))
317		f.filename = "unmapped filename"; 
318	printk("----------- [cut here ] --------- [please bite here ] ---------\n");
319	printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line);
320} 
321
322void out_of_line_bug(void)
323{ 
324	BUG(); 
325} 
326
327static DEFINE_SPINLOCK(die_lock);
328static int die_owner = -1;
329
330void oops_begin(void)
331{
332	int cpu = safe_smp_processor_id(); 
333	/* racy, but better than risking deadlock. */ 
334	local_irq_disable();
335	if (!spin_trylock(&die_lock)) { 
336		if (cpu == die_owner) 
337			/* nested oops. should stop eventually */;
338		else
339			spin_lock(&die_lock); 
340	}
341	die_owner = cpu; 
342	console_verbose();
343	bust_spinlocks(1); 
344}
345
346void oops_end(void)
347{ 
348	die_owner = -1;
349	bust_spinlocks(0); 
350	spin_unlock(&die_lock); 
351	if (panic_on_oops)
352		panic("Oops"); 
353} 
354
355void __die(const char * str, struct pt_regs * regs, long err)
356{
357	static int die_counter;
358	printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter);
359#ifdef CONFIG_PREEMPT
360	printk("PREEMPT ");
361#endif
362#ifdef CONFIG_SMP
363	printk("SMP ");
364#endif
365#ifdef CONFIG_DEBUG_PAGEALLOC
366	printk("DEBUG_PAGEALLOC");
367#endif
368	printk("\n");
369	notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
370	show_registers(regs);
371	/* Executive summary in case the oops scrolled away */
372	printk(KERN_ALERT "RIP ");
373	printk_address(regs->rip); 
374	printk(" RSP <%016lx>\n", regs->rsp); 
375}
376
377void die(const char * str, struct pt_regs * regs, long err)
378{
379	oops_begin();
380	handle_BUG(regs);
381	__die(str, regs, err);
382	oops_end();
383	do_exit(SIGSEGV); 
384}
385static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
386{
387	if (!(regs->eflags & VM_MASK) && (regs->cs == __KERNEL_CS))
388		die(str, regs, err);
389}
390
391void die_nmi(char *str, struct pt_regs *regs)
392{
393	oops_begin();
394	/*
395	 * We are in trouble anyway, lets at least try
396	 * to get a message out.
397	 */
398	printk(str, safe_smp_processor_id());
399	show_registers(regs);
400	if (panic_on_timeout || panic_on_oops)
401		panic("nmi watchdog");
402	printk("console shuts up ...\n");
403	oops_end();
404	do_exit(SIGSEGV);
405}
406
407static void do_trap(int trapnr, int signr, char *str, 
408			   struct pt_regs * regs, long error_code, siginfo_t *info)
409{
410	conditional_sti(regs);
411
412#ifdef CONFIG_CHECKING
413       { 
414               unsigned long gs; 
415               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
416               rdmsrl(MSR_GS_BASE, gs); 
417               if (gs != (unsigned long)pda) { 
418                       wrmsrl(MSR_GS_BASE, pda); 
419                       printk("%s: wrong gs %lx expected %p rip %lx\n", str, gs, pda,
420			      regs->rip);
421               }
422       }
423#endif
424
425	if ((regs->cs & 3)  != 0) { 
426		struct task_struct *tsk = current;
427
428		if (exception_trace && unhandled_signal(tsk, signr))
429			printk(KERN_INFO
430			       "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
431			       tsk->comm, tsk->pid, str,
432			       regs->rip,regs->rsp,error_code); 
433
434		tsk->thread.error_code = error_code;
435		tsk->thread.trap_no = trapnr;
436		if (info)
437			force_sig_info(signr, info, tsk);
438		else
439			force_sig(signr, tsk);
440		return;
441	}
442
443
444	/* kernel trap */ 
445	{	     
446		const struct exception_table_entry *fixup;
447		fixup = search_exception_tables(regs->rip);
448		if (fixup) {
449			regs->rip = fixup->fixup;
450		} else	
451			die(str, regs, error_code);
452		return;
453	}
454}
455
456#define DO_ERROR(trapnr, signr, str, name) \
457asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
458{ \
459	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
460							== NOTIFY_STOP) \
461		return; \
462	do_trap(trapnr, signr, str, regs, error_code, NULL); \
463}
464
465#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
466asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
467{ \
468	siginfo_t info; \
469	info.si_signo = signr; \
470	info.si_errno = 0; \
471	info.si_code = sicode; \
472	info.si_addr = (void __user *)siaddr; \
473	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
474							== NOTIFY_STOP) \
475		return; \
476	do_trap(trapnr, signr, str, regs, error_code, &info); \
477}
478
479DO_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->rip)
480DO_ERROR( 4, SIGSEGV, "overflow", overflow)
481DO_ERROR( 5, SIGSEGV, "bounds", bounds)
482DO_ERROR_INFO( 6, SIGILL,  "invalid operand", invalid_op, ILL_ILLOPN, regs->rip)
483DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
484DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
485DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
486DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
487DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
488DO_ERROR(18, SIGSEGV, "reserved", reserved)
489
490#define DO_ERROR_STACK(trapnr, signr, str, name) \
491asmlinkage void *do_##name(struct pt_regs * regs, long error_code) \
492{ \
493	struct pt_regs *pr = ((struct pt_regs *)(current->thread.rsp0))-1; \
494	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
495							== NOTIFY_STOP) \
496		return regs; \
497	if (regs->cs & 3) { \
498		memcpy(pr, regs, sizeof(struct pt_regs)); \
499		regs = pr; \
500	} \
501	do_trap(trapnr, signr, str, regs, error_code, NULL); \
502	return regs;		\
503}
504
505DO_ERROR_STACK(12, SIGBUS,  "stack segment", stack_segment)
506DO_ERROR_STACK( 8, SIGSEGV, "double fault", double_fault)
507
508asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
509{
510	conditional_sti(regs);
511
512#ifdef CONFIG_CHECKING
513       { 
514               unsigned long gs; 
515               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
516               rdmsrl(MSR_GS_BASE, gs); 
517               if (gs != (unsigned long)pda) { 
518                       wrmsrl(MSR_GS_BASE, pda); 
519		       oops_in_progress++;
520                       printk("general protection handler: wrong gs %lx expected %p\n", gs, pda);
521		       oops_in_progress--;
522               }
523       }
524#endif
525
526	if ((regs->cs & 3)!=0) { 
527		struct task_struct *tsk = current;
528
529		if (exception_trace && unhandled_signal(tsk, SIGSEGV))
530			printk(KERN_INFO
531		       "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
532			       tsk->comm, tsk->pid,
533			       regs->rip,regs->rsp,error_code); 
534
535		tsk->thread.error_code = error_code;
536		tsk->thread.trap_no = 13;
537		force_sig(SIGSEGV, tsk);
538		return;
539	} 
540
541	/* kernel gp */
542	{
543		const struct exception_table_entry *fixup;
544		fixup = search_exception_tables(regs->rip);
545		if (fixup) {
546			regs->rip = fixup->fixup;
547			return;
548		}
549		if (notify_die(DIE_GPF, "general protection fault", regs,
550					error_code, 13, SIGSEGV) == NOTIFY_STOP)
551			return;
552		die("general protection fault", regs, error_code);
553	}
554}
555
556static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
557{
558	printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
559	printk("You probably have a hardware problem with your RAM chips\n");
560
561	/* Clear and disable the memory parity error line. */
562	reason = (reason & 0xf) | 4;
563	outb(reason, 0x61);
564}
565
566static void io_check_error(unsigned char reason, struct pt_regs * regs)
567{
568	printk("NMI: IOCK error (debug interrupt?)\n");
569	show_registers(regs);
570
571	/* Re-enable the IOCK line, wait for a few seconds */
572	reason = (reason & 0xf) | 8;
573	outb(reason, 0x61);
574	mdelay(2000);
575	reason &= ~8;
576	outb(reason, 0x61);
577}
578
579static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
580{	printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
581	printk("Dazed and confused, but trying to continue\n");
582	printk("Do you have a strange power saving mode enabled?\n");
583}
584
585asmlinkage void default_do_nmi(struct pt_regs *regs)
586{
587	unsigned char reason = 0;
588
589	/* Only the BSP gets external NMIs from the system.  */
590	if (!smp_processor_id())
591		reason = get_nmi_reason();
592
593	if (!(reason & 0xc0)) {
594		if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
595								== NOTIFY_STOP)
596			return;
597#ifdef CONFIG_X86_LOCAL_APIC
598		/*
599		 * Ok, so this is none of the documented NMI sources,
600		 * so it must be the NMI watchdog.
601		 */
602		if (nmi_watchdog > 0) {
603			nmi_watchdog_tick(regs,reason);
604			return;
605		}
606#endif
607		unknown_nmi_error(reason, regs);
608		return;
609	}
610	if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP)
611		return; 
612
613	/* AK: following checks seem to be broken on modern chipsets. FIXME */
614
615	if (reason & 0x80)
616		mem_parity_error(reason, regs);
617	if (reason & 0x40)
618		io_check_error(reason, regs);
619}
620
621asmlinkage void do_int3(struct pt_regs * regs, long error_code)
622{
623	if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
624		return;
625	}
626	do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
627	return;
628}
629
630/* runs on IST stack. */
631asmlinkage void *do_debug(struct pt_regs * regs, unsigned long error_code)
632{
633	struct pt_regs *pr;
634	unsigned long condition;
635	struct task_struct *tsk = current;
636	siginfo_t info;
637
638	pr = (struct pt_regs *)(current->thread.rsp0)-1;
639	if (regs->cs & 3) {
640		memcpy(pr, regs, sizeof(struct pt_regs));
641		regs = pr;
642	}	
643
644#ifdef CONFIG_CHECKING
645       { 
646	       /* RED-PEN interaction with debugger - could destroy gs */
647               unsigned long gs; 
648               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
649               rdmsrl(MSR_GS_BASE, gs); 
650               if (gs != (unsigned long)pda) { 
651                       wrmsrl(MSR_GS_BASE, pda); 
652                       printk("debug handler: wrong gs %lx expected %p\n", gs, pda);
653               }
654       }
655#endif
656
657	asm("movq %%db6,%0" : "=r" (condition));
658
659	if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
660						SIGTRAP) == NOTIFY_STOP) {
661		return regs;
662	}
663	conditional_sti(regs);
664
665	/* Mask out spurious debug traps due to lazy DR7 setting */
666	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
667		if (!tsk->thread.debugreg7) { 
668			goto clear_dr7;
669		}
670	}
671
672	tsk->thread.debugreg6 = condition;
673
674	/* Mask out spurious TF errors due to lazy TF clearing */
675	if ((condition & DR_STEP) &&
676	    (notify_die(DIE_DEBUGSTEP, "debugstep", regs, condition,
677			1, SIGTRAP) != NOTIFY_STOP)) {
678		/*
679		 * The TF error should be masked out only if the current
680		 * process is not traced and if the TRAP flag has been set
681		 * previously by a tracing process (condition detected by
682		 * the PT_DTRACE flag); remember that the i386 TRAP flag
683		 * can be modified by the process itself in user mode,
684		 * allowing programs to debug themselves without the ptrace()
685		 * interface.
686		 */
687                if ((regs->cs & 3) == 0)
688                       goto clear_TF_reenable;
689		if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
690			goto clear_TF;
691	}
692
693	/* Ok, finally something we can handle */
694	tsk->thread.trap_no = 1;
695	tsk->thread.error_code = error_code;
696	info.si_signo = SIGTRAP;
697	info.si_errno = 0;
698	info.si_code = TRAP_BRKPT;
699	if ((regs->cs & 3) == 0) 
700		goto clear_dr7; 
701
702	info.si_addr = (void __user *)regs->rip;
703	force_sig_info(SIGTRAP, &info, tsk);	
704clear_dr7:
705	asm volatile("movq %0,%%db7"::"r"(0UL));
706	notify_die(DIE_DEBUG, "debug", regs, condition, 1, SIGTRAP);
707	return regs;
708
709clear_TF_reenable:
710	set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
711
712clear_TF:
713	/* RED-PEN could cause spurious errors */
714	if (notify_die(DIE_DEBUG, "debug2", regs, condition, 1, SIGTRAP) 
715								!= NOTIFY_STOP)
716	regs->eflags &= ~TF_MASK;
717	return regs;	
718}
719
720static int kernel_math_error(struct pt_regs *regs, char *str)
721{
722	const struct exception_table_entry *fixup;
723	fixup = search_exception_tables(regs->rip);
724	if (fixup) {
725		regs->rip = fixup->fixup;
726		return 1;
727	}
728	notify_die(DIE_GPF, str, regs, 0, 16, SIGFPE);
729#if 0
730	/* This should be a die, but warn only for now */
731	die(str, regs, 0);
732#else
733	printk(KERN_DEBUG "%s: %s at ", current->comm, str);
734	printk_address(regs->rip);
735	printk("\n");
736#endif
737	return 0;
738}
739
740/*
741 * Note that we play around with the 'TS' bit in an attempt to get
742 * the correct behaviour even in the presence of the asynchronous
743 * IRQ13 behaviour
744 */
745asmlinkage void do_coprocessor_error(struct pt_regs *regs)
746{
747	void __user *rip = (void __user *)(regs->rip);
748	struct task_struct * task;
749	siginfo_t info;
750	unsigned short cwd, swd;
751
752	conditional_sti(regs);
753	if ((regs->cs & 3) == 0 &&
754	    kernel_math_error(regs, "kernel x87 math error"))
755		return;
756
757	/*
758	 * Save the info for the exception handler and clear the error.
759	 */
760	task = current;
761	save_init_fpu(task);
762	task->thread.trap_no = 16;
763	task->thread.error_code = 0;
764	info.si_signo = SIGFPE;
765	info.si_errno = 0;
766	info.si_code = __SI_FAULT;
767	info.si_addr = rip;
768	/*
769	 * (~cwd & swd) will mask out exceptions that are not set to unmasked
770	 * status.  0x3f is the exception bits in these regs, 0x200 is the
771	 * C1 reg you need in case of a stack fault, 0x040 is the stack
772	 * fault bit.  We should only be taking one exception at a time,
773	 * so if this combination doesn't produce any single exception,
774	 * then we have a bad program that isn't synchronizing its FPU usage
775	 * and it will suffer the consequences since we won't be able to
776	 * fully reproduce the context of the exception
777	 */
778	cwd = get_fpu_cwd(task);
779	swd = get_fpu_swd(task);
780	switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
781		case 0x000:
782		default:
783			break;
784		case 0x001: /* Invalid Op */
785		case 0x041: /* Stack Fault */
786		case 0x241: /* Stack Fault | Direction */
787			info.si_code = FPE_FLTINV;
788			break;
789		case 0x002: /* Denormalize */
790		case 0x010: /* Underflow */
791			info.si_code = FPE_FLTUND;
792			break;
793		case 0x004: /* Zero Divide */
794			info.si_code = FPE_FLTDIV;
795			break;
796		case 0x008: /* Overflow */
797			info.si_code = FPE_FLTOVF;
798			break;
799		case 0x020: /* Precision */
800			info.si_code = FPE_FLTRES;
801			break;
802	}
803	force_sig_info(SIGFPE, &info, task);
804}
805
806asmlinkage void bad_intr(void)
807{
808	printk("bad interrupt"); 
809}
810
811asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
812{
813	void __user *rip = (void __user *)(regs->rip);
814	struct task_struct * task;
815	siginfo_t info;
816	unsigned short mxcsr;
817
818	conditional_sti(regs);
819	if ((regs->cs & 3) == 0 &&
820        	kernel_math_error(regs, "simd math error"))
821		return;
822
823	/*
824	 * Save the info for the exception handler and clear the error.
825	 */
826	task = current;
827	save_init_fpu(task);
828	task->thread.trap_no = 19;
829	task->thread.error_code = 0;
830	info.si_signo = SIGFPE;
831	info.si_errno = 0;
832	info.si_code = __SI_FAULT;
833	info.si_addr = rip;
834	/*
835	 * The SIMD FPU exceptions are handled a little differently, as there
836	 * is only a single status/control register.  Thus, to determine which
837	 * unmasked exception was caught we must mask the exception mask bits
838	 * at 0x1f80, and then use these to mask the exception bits at 0x3f.
839	 */
840	mxcsr = get_fpu_mxcsr(task);
841	switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
842		case 0x000:
843		default:
844			break;
845		case 0x001: /* Invalid Op */
846			info.si_code = FPE_FLTINV;
847			break;
848		case 0x002: /* Denormalize */
849		case 0x010: /* Underflow */
850			info.si_code = FPE_FLTUND;
851			break;
852		case 0x004: /* Zero Divide */
853			info.si_code = FPE_FLTDIV;
854			break;
855		case 0x008: /* Overflow */
856			info.si_code = FPE_FLTOVF;
857			break;
858		case 0x020: /* Precision */
859			info.si_code = FPE_FLTRES;
860			break;
861	}
862	force_sig_info(SIGFPE, &info, task);
863}
864
865asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
866{
867}
868
869asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
870{
871}
872
873/*
874 *  'math_state_restore()' saves the current math information in the
875 * old math state array, and gets the new ones from the current task
876 *
877 * Careful.. There are problems with IBM-designed IRQ13 behaviour.
878 * Don't touch unless you *really* know how it works.
879 */
880asmlinkage void math_state_restore(void)
881{
882	struct task_struct *me = current;
883	clts();			/* Allow maths ops (or we recurse) */
884
885	if (!used_math())
886		init_fpu(me);
887	restore_fpu_checking(&me->thread.i387.fxsave);
888	me->thread_info->status |= TS_USEDFPU;
889}
890
891void do_call_debug(struct pt_regs *regs) 
892{ 
893	notify_die(DIE_CALL, "debug call", regs, 0, 255, SIGINT); 
894}
895
896void __init trap_init(void)
897{
898	set_intr_gate(0,&divide_error);
899	set_intr_gate_ist(1,&debug,DEBUG_STACK);
900	set_intr_gate_ist(2,&nmi,NMI_STACK);
901	set_system_gate(3,&int3);
902	set_system_gate(4,&overflow);	/* int4-5 can be called from all */
903	set_system_gate(5,&bounds);
904	set_intr_gate(6,&invalid_op);
905	set_intr_gate(7,&device_not_available);
906	set_intr_gate_ist(8,&double_fault, DOUBLEFAULT_STACK);
907	set_intr_gate(9,&coprocessor_segment_overrun);
908	set_intr_gate(10,&invalid_TSS);
909	set_intr_gate(11,&segment_not_present);
910	set_intr_gate_ist(12,&stack_segment,STACKFAULT_STACK);
911	set_intr_gate(13,&general_protection);
912	set_intr_gate(14,&page_fault);
913	set_intr_gate(15,&spurious_interrupt_bug);
914	set_intr_gate(16,&coprocessor_error);
915	set_intr_gate(17,&alignment_check);
916#ifdef CONFIG_X86_MCE
917	set_intr_gate_ist(18,&machine_check, MCE_STACK); 
918#endif
919	set_intr_gate(19,&simd_coprocessor_error);
920
921#ifdef CONFIG_IA32_EMULATION
922	set_system_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
923#endif
924       
925	set_intr_gate(KDB_VECTOR, call_debug);
926       
927	/*
928	 * Should be a barrier for any external CPU state.
929	 */
930	cpu_init();
931}
932
933
934/* Actual parsing is done early in setup.c. */
935static int __init oops_dummy(char *s)
936{ 
937	panic_on_oops = 1;
938	return -1; 
939} 
940__setup("oops=", oops_dummy); 
941
942static int __init kstack_setup(char *s)
943{
944	kstack_depth_to_print = simple_strtoul(s,NULL,0);
945	return 0;
946}
947__setup("kstack=", kstack_setup);
948