traps.c (8990c1bc4be46473ad19bf2fa612ca57286f3df4) traps.c (515b029d005b5694cf612a0a5ca6f861a7e45362)
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
7 * Copyright (C) 1995, 1996 Paul M. Antoine
8 * Copyright (C) 1998 Ulf Carlsson

--- 69 unchanged lines hidden (view full) ---

78extern asmlinkage void handle_mdmx(void);
79extern asmlinkage void handle_watch(void);
80extern asmlinkage void handle_mt(void);
81extern asmlinkage void handle_dsp(void);
82extern asmlinkage void handle_mcheck(void);
83extern asmlinkage void handle_reserved(void);
84
85extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
7 * Copyright (C) 1995, 1996 Paul M. Antoine
8 * Copyright (C) 1998 Ulf Carlsson

--- 69 unchanged lines hidden (view full) ---

78extern asmlinkage void handle_mdmx(void);
79extern asmlinkage void handle_watch(void);
80extern asmlinkage void handle_mt(void);
81extern asmlinkage void handle_dsp(void);
82extern asmlinkage void handle_mcheck(void);
83extern asmlinkage void handle_reserved(void);
84
85extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
86 struct mips_fpu_struct *ctx, int has_fpu);
86 struct mips_fpu_struct *ctx, int has_fpu,
87 void *__user *fault_addr);
87
88void (*board_be_init)(void);
89int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
90void (*board_nmi_handler_setup)(void);
91void (*board_ejtag_handler_setup)(void);
92void (*board_bind_eic_interrupt)(int irq, int regset);
93
94

--- 561 unchanged lines hidden (view full) ---

656
657 info.si_code = FPE_INTOVF;
658 info.si_signo = SIGFPE;
659 info.si_errno = 0;
660 info.si_addr = (void __user *) regs->cp0_epc;
661 force_sig_info(SIGFPE, &info, current);
662}
663
88
89void (*board_be_init)(void);
90int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
91void (*board_nmi_handler_setup)(void);
92void (*board_ejtag_handler_setup)(void);
93void (*board_bind_eic_interrupt)(int irq, int regset);
94
95

--- 561 unchanged lines hidden (view full) ---

657
658 info.si_code = FPE_INTOVF;
659 info.si_signo = SIGFPE;
660 info.si_errno = 0;
661 info.si_addr = (void __user *) regs->cp0_epc;
662 force_sig_info(SIGFPE, &info, current);
663}
664
665static int process_fpemu_return(int sig, void __user *fault_addr)
666{
667 if (sig == SIGSEGV || sig == SIGBUS) {
668 struct siginfo si = {0};
669 si.si_addr = fault_addr;
670 si.si_signo = sig;
671 if (sig == SIGSEGV) {
672 if (find_vma(current->mm, (unsigned long)fault_addr))
673 si.si_code = SEGV_ACCERR;
674 else
675 si.si_code = SEGV_MAPERR;
676 } else {
677 si.si_code = BUS_ADRERR;
678 }
679 force_sig_info(sig, &si, current);
680 return 1;
681 } else if (sig) {
682 force_sig(sig, current);
683 return 1;
684 } else {
685 return 0;
686 }
687}
688
664/*
665 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
666 */
667asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
668{
689/*
690 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
691 */
692asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
693{
669 siginfo_t info;
694 siginfo_t info = {0};
670
671 if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
672 == NOTIFY_STOP)
673 return;
674 die_if_kernel("FP exception in kernel code", regs);
675
676 if (fcr31 & FPU_CSR_UNI_X) {
677 int sig;
695
696 if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
697 == NOTIFY_STOP)
698 return;
699 die_if_kernel("FP exception in kernel code", regs);
700
701 if (fcr31 & FPU_CSR_UNI_X) {
702 int sig;
703 void __user *fault_addr = NULL;
678
679 /*
680 * Unimplemented operation exception. If we've got the full
681 * software emulator on-board, let's use it...
682 *
683 * Force FPU to dump state into task/thread context. We're
684 * moving a lot of data here for what is probably a single
685 * instruction, but the alternative is to pre-decode the FP
686 * register operands before invoking the emulator, which seems
687 * a bit extreme for what should be an infrequent event.
688 */
689 /* Ensure 'resume' not overwrite saved fp context again. */
690 lose_fpu(1);
691
692 /* Run the emulator */
704
705 /*
706 * Unimplemented operation exception. If we've got the full
707 * software emulator on-board, let's use it...
708 *
709 * Force FPU to dump state into task/thread context. We're
710 * moving a lot of data here for what is probably a single
711 * instruction, but the alternative is to pre-decode the FP
712 * register operands before invoking the emulator, which seems
713 * a bit extreme for what should be an infrequent event.
714 */
715 /* Ensure 'resume' not overwrite saved fp context again. */
716 lose_fpu(1);
717
718 /* Run the emulator */
693 sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1);
719 sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
720 &fault_addr);
694
695 /*
696 * We can't allow the emulated instruction to leave any of
697 * the cause bit set in $fcr31.
698 */
699 current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
700
701 /* Restore the hardware register state */
702 own_fpu(1); /* Using the FPU again. */
703
704 /* If something went wrong, signal */
721
722 /*
723 * We can't allow the emulated instruction to leave any of
724 * the cause bit set in $fcr31.
725 */
726 current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
727
728 /* Restore the hardware register state */
729 own_fpu(1); /* Using the FPU again. */
730
731 /* If something went wrong, signal */
705 if (sig)
706 force_sig(sig, current);
732 process_fpemu_return(sig, fault_addr);
707
708 return;
709 } else if (fcr31 & FPU_CSR_INV_X)
710 info.si_code = FPE_FLTINV;
711 else if (fcr31 & FPU_CSR_DIV_X)
712 info.si_code = FPE_FLTDIV;
713 else if (fcr31 & FPU_CSR_OVF_X)
714 info.si_code = FPE_FLTOVF;

--- 276 unchanged lines hidden (view full) ---

991 own_fpu(1);
992 else { /* First time FPU user. */
993 init_fpu();
994 set_used_math();
995 }
996
997 if (!raw_cpu_has_fpu) {
998 int sig;
733
734 return;
735 } else if (fcr31 & FPU_CSR_INV_X)
736 info.si_code = FPE_FLTINV;
737 else if (fcr31 & FPU_CSR_DIV_X)
738 info.si_code = FPE_FLTDIV;
739 else if (fcr31 & FPU_CSR_OVF_X)
740 info.si_code = FPE_FLTOVF;

--- 276 unchanged lines hidden (view full) ---

1017 own_fpu(1);
1018 else { /* First time FPU user. */
1019 init_fpu();
1020 set_used_math();
1021 }
1022
1023 if (!raw_cpu_has_fpu) {
1024 int sig;
1025 void __user *fault_addr = NULL;
999 sig = fpu_emulator_cop1Handler(regs,
1026 sig = fpu_emulator_cop1Handler(regs,
1000 &current->thread.fpu, 0);
1001 if (sig)
1002 force_sig(sig, current);
1003 else
1027 &current->thread.fpu,
1028 0, &fault_addr);
1029 if (!process_fpemu_return(sig, fault_addr))
1004 mt_ase_fp_affinity();
1005 }
1006
1007 return;
1008
1009 case 2:
1010 raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
1011 return;

--- 760 unchanged lines hidden ---
1030 mt_ase_fp_affinity();
1031 }
1032
1033 return;
1034
1035 case 2:
1036 raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
1037 return;

--- 760 unchanged lines hidden ---