>>>>> On Wed, 06 Oct 2004 10:19:20 +0900 (JST), Atsushi Nemoto
>>>>> <anemo@mba.ocn.ne.jp> 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
|