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, ¤t->thread.fpu, 1); | 719 sig = fpu_emulator_cop1Handler(regs, ¤t->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 ¤t->thread.fpu, 0); 1001 if (sig) 1002 force_sig(sig, current); 1003 else | 1027 ¤t->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 --- |