[kernel] r15671 - dists/sid/linux-2.6/debian/patches/bugfix/mips

Ben Hutchings benh at alioth.debian.org
Thu May 13 01:18:26 UTC 2010


Author: benh
Date: Thu May 13 01:18:25 2010
New Revision: 15671

Log:
Restore patch wrongly removed in r15669

Added:
   dists/sid/linux-2.6/debian/patches/bugfix/mips/fpu-emulator.patch

Added: dists/sid/linux-2.6/debian/patches/bugfix/mips/fpu-emulator.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/mips/fpu-emulator.patch	Thu May 13 01:18:25 2010	(r15671)
@@ -0,0 +1,99 @@
+From: Shane McDonald <mcdonald.shane at gmail.com>
+Date: Fri, 7 May 2010 05:26:57 +0000 (-0600)
+Subject: MIPS FPU emulator: allow Cause bits of FCSR to be writeable by ctc1
+X-Git-Url: http://www.linux-mips.org/git?p=linux.git;a=commitdiff_plain;h=2c8fb481214e608f6b9a71aa85651d9ddf7fd6e4
+
+MIPS FPU emulator: allow Cause bits of FCSR to be writeable by ctc1
+
+In the FPU emulator code of the MIPS, the Cause bits of the FCSR register
+are not currently writeable by the ctc1 instruction.  In odd corner cases,
+this can cause problems.  For example, a case existed where a divide-by-zero
+exception was generated by the FPU, and the signal handler attempted to
+restore the FPU registers to their state before the exception occurred.  In
+this particular setup, writing the old value to the FCSR register would
+cause another divide-by-zero exception to occur immediately.  The solution
+is to change the ctc1 instruction emulator code to allow the Cause bits of
+the FCSR register to be writeable.  This is the behaviour of the hardware
+that the code is emulating.
+
+This problem was found by Shane McDonald, but the credit for the fix goes
+to Kevin Kissell.  In Kevin's words:
+
+I submit that the bug is indeed in that ctc_op:  case of the emulator.  The
+Cause bits (17:12) are supposed to be writable by that instruction, but the
+CTC1 emulation won't let them be updated by the instruction.  I think that
+actually if you just completely removed lines 387-388 [...] things would
+work a good deal better.  At least, it would be a more accurate emulation of
+the architecturally defined FPU.  If I wanted to be really, really pedantic
+(which I sometimes do), I'd also protect the reserved bits that aren't
+necessarily writable.
+
+Signed-off-by: Shane McDonald <mcdonald.shane at gmail.com>
+To: anemo at mba.ocn.ne.jp
+To: kevink at paralogos.com
+To: sshtylyov at mvista.com
+Patchwork: http://patchwork.linux-mips.org/patch/1205/
+Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
+(cherry picked from commit 635be78c7c80d4c61f0f16b6132a730d7668cb43)
+---
+
+diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
+index a581d60..608dc97 100644
+--- a/arch/mips/include/asm/mipsregs.h
++++ b/arch/mips/include/asm/mipsregs.h
+@@ -135,6 +135,12 @@
+ #define FPU_CSR_COND7   0x80000000      /* $fcc7 */
+ 
+ /*
++ * Bits 18 - 20 of the FPU Status Register will be read as 0,
++ * and should be written as zero.
++ */
++#define FPU_CSR_RSVD	0x001c0000
++
++/*
+  * X the exception cause indicator
+  * E the exception enable
+  * S the sticky/flag bit
+@@ -161,7 +167,8 @@
+ #define FPU_CSR_UDF_S   0x00000008
+ #define FPU_CSR_INE_S   0x00000004
+ 
+-/* rounding mode */
++/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
++#define FPU_CSR_RM	0x00000003
+ #define FPU_CSR_RN      0x0     /* nearest */
+ #define FPU_CSR_RZ      0x1     /* towards zero */
+ #define FPU_CSR_RU      0x2     /* towards +Infinity */
+diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
+index 454b539..c15d94b 100644
+--- a/arch/mips/math-emu/cp1emu.c
++++ b/arch/mips/math-emu/cp1emu.c
+@@ -75,6 +75,9 @@ struct mips_fpu_emulator_stats fpuemustats;
+ #define FPCREG_RID	0	/* $0  = revision id */
+ #define FPCREG_CSR	31	/* $31 = csr */
+ 
++/* Determine rounding mode from the RM bits of the FCSR */
++#define modeindex(v) ((v) & FPU_CSR_RM)
++
+ /* Convert Mips rounding mode (0..3) to IEEE library modes. */
+ static const unsigned char ieee_rm[4] = {
+ 	[FPU_CSR_RN] = IEEE754_RN,
+@@ -381,10 +384,14 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+ 					(void *) (xcp->cp0_epc),
+ 					MIPSInst_RT(ir), value);
+ #endif
+-				value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
+-				ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
+-				/* convert to ieee library modes */
+-				ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
++
++				/*
++				 * Don't write reserved bits,
++				 * and convert to ieee library modes
++				 */
++				ctx->fcr31 = (value &
++						~(FPU_CSR_RSVD | FPU_CSR_RM)) |
++						ieee_rm[modeindex(value)];
+ 			}
+ 			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+ 				return SIGFPE;



More information about the Kernel-svn-changes mailing list