Re: [PATCH 06/15] mips: clear upper bits of FP registers on emulator writes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jan 27, 2014 at 09:06:52PM +0300, Sergei Shtylyov wrote:
> Hello.
> 
> On 01/27/2014 06:23 PM, Paul Burton wrote:
> 
> >The upper bits of an FP register are architecturally defined as
> >unpredictable following an instructions which only writes the lower
> >bits. The prior behaviour of the kernel is to leave them unmodified.
> >This patch modifies that to clear the upper bits to zero. This is what
> >the MSA architecture reference manual specifies should happen for its
> >wider registers and is still permissible for scalar FP instructions
> >given the bits unpredictability there.
> 
> >Signed-off-by: Paul Burton <paul.burton@xxxxxxxxxx>
> >---
> >  arch/mips/math-emu/cp1emu.c | 25 ++++++++++++++++++++-----
> >  1 file changed, 20 insertions(+), 5 deletions(-)
> 
> >diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
> >index 9144842..c484f5f 100644
> >--- a/arch/mips/math-emu/cp1emu.c
> >+++ b/arch/mips/math-emu/cp1emu.c
> >@@ -884,20 +884,35 @@ static inline int cop1_64bit(struct pt_regs *xcp)
> >  } while (0)
> >
> >  #define SITOREG(si, x) do {						\
> >-	if (cop1_64bit(xcp))						\
> >+	if (cop1_64bit(xcp)) {						\
> >+		unsigned i;						\
> >  		set_fpr32(&ctx->fpr[x], 0, si);				\
> >-	else								\
> >+		for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++)	\
> >+			set_fpr32(&ctx->fpr[x], i, 0);			\
> >+	} else {							\
> >  		set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si);		\
> >+	}								\
> >  } while (0)
> >
> >  #define SIFROMHREG(si, x)	((si) = get_fpr32(&ctx->fpr[x], 1))
> >-#define SITOHREG(si, x)		set_fpr32(&ctx->fpr[x], 1, si)
> >+
> >+#define SITOHREG(si, x) do {						\
> >+	unsigned i;							\
> >+	set_fpr32(&ctx->fpr[x], 1, si);					\
> >+	for (i = 2; i < ARRAY_SIZE(ctx->fpr[x].val32); i++)		\
> >+			set_fpr32(&ctx->fpr[x], i, 0);			\
> 
>    This line is over-indented, no? Compare the loop below...
> 

Indeed it is, well spotted :)

Thanks,
    Paul

> >+} while (0)
> >
> >  #define DIFROMREG(di, x) \
> >  	((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0))
> >
> >-#define DITOREG(di, x) \
> >-	set_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0, di)
> >+#define DITOREG(di, x) do {						\
> >+	unsigned fpr, i;						\
> >+	fpr = (x) & ~(cop1_64bit(xcp) == 0);				\
> >+	set_fpr64(&ctx->fpr[fpr], 0, di);				\
> >+	for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++)		\
> >+		set_fpr64(&ctx->fpr[fpr], i, 0);			\
> >+} while (0)
> 
> WBR, Sergei
> 



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux