>>>>> On Wed, 06 Oct 2004 10:19:20 +0900 (JST), Atsushi Nemoto <anemo@xxxxxxxxxxxxx> said: anemo> Also, there is another problem in the math-emu. While math-emu anemo> is not reentrant, it will not work properly if a process lose anemo> ownership in the math-emu and another process uses the anemo> math-emu. One possible fix is to save/restore ieee754_csr on anemo> get_user/put_user. I will post a patch later. Here it is. Can be applied bath 2.4 and 2.6. --- linux-mips/arch/mips/math-emu/cp1emu.c Wed Sep 1 10:47:21 2004 +++ linux/arch/mips/math-emu/cp1emu.c Wed Oct 6 12:34:43 2004 @@ -51,6 +51,24 @@ #include "ieee754.h" #include "dsemul.h" +#define math_put_user(x, ptr) \ +({ \ + long math_pu_err; \ + struct ieee754_csr pu_csr_save; \ + pu_csr_save = ieee754_csr; \ + math_pu_err = put_user(x, ptr); \ + ieee754_csr = pu_csr_save; \ + math_pu_err; \ +}) +#define math_get_user(x, ptr) \ +({ \ + long math_gu_err; \ + struct ieee754_csr gu_csr_save; \ + gu_csr_save = ieee754_csr; \ + math_gu_err = get_user(x, ptr); \ + ieee754_csr = gu_csr_save; \ + math_gu_err; \ +}) /* Strap kernel emulator for full MIPS IV emulation */ #ifdef __mips @@ -199,7 +217,7 @@ vaddr_t emulpc, contpc; unsigned int cond; - if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) { + if (math_get_user(ir, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -230,7 +248,7 @@ #endif return SIGILL; } - if (get_user(ir, (mips_instruction *) emulpc)) { + if (math_get_user(ir, (mips_instruction *) emulpc)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -254,7 +272,7 @@ u64 val; fpuemuprivate.stats.loads++; - if (get_user(val, va)) { + if (math_get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -269,7 +287,7 @@ fpuemuprivate.stats.stores++; DIFROMREG(val, MIPSInst_RT(ir)); - if (put_user(val, va)) { + if (math_put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -283,7 +301,7 @@ u32 val; fpuemuprivate.stats.loads++; - if (get_user(val, va)) { + if (math_get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -310,7 +328,7 @@ } #endif SIFROMREG(val, MIPSInst_RT(ir)); - if (put_user(val, va)) { + if (math_put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -449,7 +467,7 @@ (xcp->cp0_epc + (MIPSInst_SIMM(ir) << 2)); - if (get_user(ir, (mips_instruction *) + if (math_get_user(ir, (mips_instruction *) REG_TO_VA xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; @@ -632,7 +650,7 @@ xcp->regs[MIPSInst_FT(ir)]); fpuemuprivate.stats.loads++; - if (get_user(val, va)) { + if (math_get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -662,7 +680,7 @@ #endif SIFROMREG(val, MIPSInst_FS(ir)); - if (put_user(val, va)) { + if (math_put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -728,7 +746,7 @@ xcp->regs[MIPSInst_FT(ir)]); fpuemuprivate.stats.loads++; - if (get_user(val, va)) { + if (math_get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -741,7 +759,7 @@ fpuemuprivate.stats.stores++; DIFROMREG(val, MIPSInst_FS(ir)); - if (put_user(val, va)) { + if (math_put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -1290,7 +1308,7 @@ do { prevepc = xcp->cp0_epc; - if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) { + if (math_get_user(insn, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- Atsushi Nemoto