Index: cp1emu.c
===================================================================
RCS file: /home/repository/sw/linux-2.2.12/linux/arch/mips/fpu_emulator/cp1emu.c,v
retrieving revision 1.5
diff -c -r1.5 cp1emu.c
*** cp1emu.c	2000/02/27 15:19:18	1.5
--- cp1emu.c	2000/03/12 12:24:06
***************
*** 767,772 ****
--- 767,774 ----
  static unsigned int	dsemul_sr;
  static void *dsemul_osys;
  
+ #define AdEL 4
+ #define AdELOAD 0x8fa00001
  
  int
  do_dsemulret(struct pt_regs *xcp)
***************
*** 774,781 ****
  #ifdef DSEMUL_TRACE
      _mon_printf ("desemulret\n");
  #endif
!     /* Restore previous Trap instruction vector */
!     (void)set_except_vector(13, dsemul_osys);
      /* Set EPC to return to post-branch instruction */
      xcp->cp0_epc = VA_TO_REG (dsemul_cpc);
      /* 
--- 776,783 ----
  #ifdef DSEMUL_TRACE
      _mon_printf ("desemulret\n");
  #endif
!     /* Restore previous exception vector */
!     (void)set_except_vector(AdEL, dsemul_osys);
      /* Set EPC to return to post-branch instruction */
      xcp->cp0_epc = VA_TO_REG (dsemul_cpc);
      /* 
***************
*** 811,833 ****
       */
      dsemul_insns = (mips_instruction *)(xcp->regs[29] & ~3);
      dsemul_insns -= 3; /* Two instructions, plus one for luck ;-) */
!     /* Verify that space exists, or can be grown, on the stack */
      if(verify_area(VERIFY_WRITE, dsemul_insns, sizeof(mips_instruction)*2)) 
  	return SIGBUS;
      
      dsemul_insns[0] = ir;
      /* 
       * Algorithmics used a system call instruction, and
!      * borrowed that vector.  It seems more prudent, and
!      * is simpler in Linux, to use a TEQ instruction, though
!      * this does require a MIPS II CPU.
       */
- #define TEQ_R0_R0 0x00000034 
-     dsemul_insns[1] = TEQ_R0_R0;
  
      dsemul_cpc = cpc;
      dsemul_sr = xcp->cp0_status;
!     dsemul_osys = set_except_vector(13, handle_dsemulret);
   
      xcp->cp0_epc = VA_TO_REG &dsemul_insns[0];
      xcp->cp0_status &= ~ST0_IM;	/* interrupt disabled inside dsemul! */
--- 813,841 ----
       */
      dsemul_insns = (mips_instruction *)(xcp->regs[29] & ~3);
      dsemul_insns -= 3; /* Two instructions, plus one for luck ;-) */
!     /* Verify that the stack pointer is not competely insane */
      if(verify_area(VERIFY_WRITE, dsemul_insns, sizeof(mips_instruction)*2)) 
  	return SIGBUS;
      
      dsemul_insns[0] = ir;
      /* 
       * Algorithmics used a system call instruction, and
!      * borrowed that vector.  As that would be catastrophic
!      * if a reschedule happens, a TEQ instruction was used
!      * in early versions of the Linux kernel emulator, since 
!      * Linux does nothing useful with Trap instructions.
!      * That does not work on R3000s, however, so here we
!      * steal the Address Error on Load vector and
!      * generate an address error on an unaligned load.
       */
  
+     /* If one is *really* paranoid, one tests for a bad stack pointer */
+     if((xcp->regs[29] & 0x3) == 0x3) dsemul_insns[1] = AdELOAD - 1;
+     else dsemul_insns[1] = AdELOAD;
+ 
      dsemul_cpc = cpc;
      dsemul_sr = xcp->cp0_status;
!     dsemul_osys = set_except_vector(AdEL, handle_dsemulret);
   
      xcp->cp0_epc = VA_TO_REG &dsemul_insns[0];
      xcp->cp0_status &= ~ST0_IM;	/* interrupt disabled inside dsemul! */
