View | Details | Raw Unified | Return to bug 56951
Collapse All | Expand All

(-)linux-2.6.7rc3-bk3/include/asm-x86_64/i387.h-o (-1 / +12 lines)
Lines 46-54 Link Here
46
		save_init_fpu(tsk); \
46
		save_init_fpu(tsk); \
47
} while (0)
47
} while (0)
48
48
49
/* Ignore delayed exceptions from user space */
50
static inline void tolerant_fwait(void)
51
{ 
52
	asm volatile("1: fwait\n"
53
		     "2:\n"
54
		     "   .section __ex_table,\"a\"\n"
55
		     "	.align 8\n"
56
		     "	.quad 1b,2b\n"
57
		     "	.previous\n");
58
} 
59
49
#define clear_fpu(tsk) do { \
60
#define clear_fpu(tsk) do { \
50
	if ((tsk)->thread_info->status & TS_USEDFPU) {		\
61
	if ((tsk)->thread_info->status & TS_USEDFPU) {		\
51
		asm volatile("fwait");				\
62
		tolerant_fwait();				\
52
		(tsk)->thread_info->status &= ~TS_USEDFPU;	\
63
		(tsk)->thread_info->status &= ~TS_USEDFPU;	\
53
		stts();						\
64
		stts();						\
54
	}							\
65
	}							\
(-)linux-2.6.7rc3-bk3/include/asm-i386/i387.h-o (-2 / +14 lines)
Lines 28-33 Link Here
28
extern void kernel_fpu_begin(void);
28
extern void kernel_fpu_begin(void);
29
#define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
29
#define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
30
30
31
/* Ignore delayed exceptions from user space */
32
static inline void tolerant_fwait(void)
33
{ 
34
	asm volatile("1: fwait\n"
35
		     "2:\n"
36
		     "   .section __ex_table,\"a\"\n"
37
		     "	.align 4\n"
38
		     "	.long 1b,2b\n"
39
		     "	.previous\n");
40
} 
41
31
/*
42
/*
32
 * These must be called with preempt disabled
43
 * These must be called with preempt disabled
33
 */
44
 */
Lines 37-44 Link Here
37
		asm volatile( "fxsave %0 ; fnclex"
48
		asm volatile( "fxsave %0 ; fnclex"
38
			      : "=m" (tsk->thread.i387.fxsave) );
49
			      : "=m" (tsk->thread.i387.fxsave) );
39
	} else {
50
	} else {
40
		asm volatile( "fnsave %0 ; fwait"
51
		asm volatile( "fnsave %0"
41
			      : "=m" (tsk->thread.i387.fsave) );
52
			      : "=m" (tsk->thread.i387.fsave) );
53
		tolerant_fwait();
42
	}
54
	}
43
	tsk->thread_info->status &= ~TS_USEDFPU;
55
	tsk->thread_info->status &= ~TS_USEDFPU;
44
}
56
}
Lines 51-57 Link Here
51
#define __clear_fpu( tsk )					\
63
#define __clear_fpu( tsk )					\
52
do {								\
64
do {								\
53
	if ((tsk)->thread_info->status & TS_USEDFPU) {		\
65
	if ((tsk)->thread_info->status & TS_USEDFPU) {		\
54
		asm volatile("fwait");				\
66
		tolerant_fwait();				\
55
		(tsk)->thread_info->status &= ~TS_USEDFPU;	\
67
		(tsk)->thread_info->status &= ~TS_USEDFPU;	\
56
		stts();						\
68
		stts();						\
57
	}							\
69
	}							\
(-)linux-2.6.7rc3-bk3/arch/i386/kernel/i8259.c-o (-1 / +1 lines)
Lines 329-335 Link Here
329
#endif
329
#endif
330
	if (ignore_fpu_irq || !boot_cpu_data.hard_math)
330
	if (ignore_fpu_irq || !boot_cpu_data.hard_math)
331
		return IRQ_NONE;
331
		return IRQ_NONE;
332
	math_error((void *)regs->eip);
332
	math_error(regs);
333
	return IRQ_HANDLED;
333
	return IRQ_HANDLED;
334
}
334
}
335
335
(-)linux-2.6.7rc3-bk3/arch/i386/kernel/traps.c-o (-4 / +26 lines)
Lines 660-671 Link Here
660
 * the correct behaviour even in the presence of the asynchronous
660
 * the correct behaviour even in the presence of the asynchronous
661
 * IRQ13 behaviour
661
 * IRQ13 behaviour
662
 */
662
 */
663
void math_error(void *eip)
663
void math_error(struct pt_regs *regs)
664
{
664
{
665
	void *eip = (void *)regs->eip;
665
	struct task_struct * task;
666
	struct task_struct * task;
666
	siginfo_t info;
667
	siginfo_t info;
667
	unsigned short cwd, swd;
668
	unsigned short cwd, swd;
668
669
670
	if ((regs->xcs & 3) == 0) {
671
		const struct exception_table_entry *fixup;
672
		fixup = search_exception_tables(regs->eip);
673
		if (fixup) {
674
			regs->eip = fixup->fixup;
675
			return;
676
		}
677
		die("kernel math error", regs, 0);
678
	}
679
669
	/*
680
	/*
670
	 * Save the info for the exception handler and clear the error.
681
	 * Save the info for the exception handler and clear the error.
671
	 */
682
	 */
Lines 719-733 Link Here
719
asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
730
asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
720
{
731
{
721
	ignore_fpu_irq = 1;
732
	ignore_fpu_irq = 1;
722
	math_error((void *)regs->eip);
733
	math_error(regs);
723
}
734
}
724
735
725
void simd_math_error(void *eip)
736
void simd_math_error(struct pt_regs *regs)
726
{
737
{
738
	void *eip = (void *)regs->eip;
727
	struct task_struct * task;
739
	struct task_struct * task;
728
	siginfo_t info;
740
	siginfo_t info;
729
	unsigned short mxcsr;
741
	unsigned short mxcsr;
730
742
743
	if ((regs->xcs & 3) == 0) {
744
		const struct exception_table_entry *fixup;
745
		fixup = search_exception_tables(regs->eip);
746
		if (fixup) {
747
			regs->eip = fixup->fixup;
748
			return;
749
		}
750
		die("kernel math error", regs, 0);
751
	}
752
731
	/*
753
	/*
732
	 * Save the info for the exception handler and clear the error.
754
	 * Save the info for the exception handler and clear the error.
733
	 */
755
	 */
Lines 776-782 Link Here
776
	if (cpu_has_xmm) {
798
	if (cpu_has_xmm) {
777
		/* Handle SIMD FPU exceptions on PIII+ processors. */
799
		/* Handle SIMD FPU exceptions on PIII+ processors. */
778
		ignore_fpu_irq = 1;
800
		ignore_fpu_irq = 1;
779
		simd_math_error((void *)regs->eip);
801
		simd_math_error(regs);
780
	} else {
802
	} else {
781
		/*
803
		/*
782
		 * Handle strange cache flush from user space exception
804
		 * Handle strange cache flush from user space exception
(-)linux-2.6.7rc3-bk3/arch/x86_64/kernel/traps.c-o (-14 / +29 lines)
Lines 686-696 Link Here
686
 * the correct behaviour even in the presence of the asynchronous
686
 * the correct behaviour even in the presence of the asynchronous
687
 * IRQ13 behaviour
687
 * IRQ13 behaviour
688
 */
688
 */
689
void math_error(void *rip)
689
asmlinkage void do_coprocessor_error(struct pt_regs * regs)
690
{
690
{
691
	void *rip = (void *)regs->rip;
691
	struct task_struct * task;
692
	struct task_struct * task;
692
	siginfo_t info;
693
	siginfo_t info;
693
	unsigned short cwd, swd;
694
	unsigned short cwd, swd;
695
696
	conditional_sti(regs);
697
	if ((regs->cs & 3) == 0) {
698
		const struct exception_table_entry *fixup;
699
		fixup = search_exception_tables(regs->rip);
700
		if (fixup) {
701
			regs->rip = fixup->fixup;
702
			return;
703
		}
704
		notify_die(DIE_GPF, "kernel math error", regs, 0, 16, SIGFPE); 
705
		die("kernel math error", regs, 0);
706
	}
707
		
694
	/*
708
	/*
695
	 * Save the info for the exception handler and clear the error.
709
	 * Save the info for the exception handler and clear the error.
696
	 */
710
	 */
Lines 740-762 Link Here
740
	force_sig_info(SIGFPE, &info, task);
754
	force_sig_info(SIGFPE, &info, task);
741
}
755
}
742
756
743
asmlinkage void do_coprocessor_error(struct pt_regs * regs)
744
{
745
	conditional_sti(regs);
746
	math_error((void *)regs->rip);
747
}
748
749
asmlinkage void bad_intr(void)
757
asmlinkage void bad_intr(void)
750
{
758
{
751
	printk("bad interrupt"); 
759
	printk("bad interrupt"); 
752
}
760
}
753
761
754
static inline void simd_math_error(void *rip)
762
asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs)
755
{
763
{
764
	void *rip = (void *)regs->rip;
756
	struct task_struct * task;
765
	struct task_struct * task;
757
	siginfo_t info;
766
	siginfo_t info;
758
	unsigned short mxcsr;
767
	unsigned short mxcsr;
759
768
769
	conditional_sti(regs);
770
	if ((regs->cs & 3) == 0) {
771
		const struct exception_table_entry *fixup;
772
		fixup = search_exception_tables(regs->rip);
773
		if (fixup) {
774
			regs->rip = fixup->fixup;
775
			return;
776
		}
777
		notify_die(DIE_GPF, "kernel simd error", regs, 0, 16, SIGFPE); 
778
		die("kernel simd error", regs, 0);
779
	}
780
760
	/*
781
	/*
761
	 * Save the info for the exception handler and clear the error.
782
	 * Save the info for the exception handler and clear the error.
762
	 */
783
	 */
Lines 799-810 Link Here
799
	force_sig_info(SIGFPE, &info, task);
820
	force_sig_info(SIGFPE, &info, task);
800
}
821
}
801
822
802
asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs)
803
{
804
	conditional_sti(regs);
805
		simd_math_error((void *)regs->rip);
806
}
807
808
asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
823
asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
809
{
824
{
810
}
825
}

Return to bug 56951