linux-mips
[Top] [All Lists]

Re: Float crash. Fix in exit_thread()

To: "Kjeld Borch Egevang" <kjelde@mips.com>, "linux-mips mailing list" <linux-mips@oss.sgi.com>
Subject: Re: Float crash. Fix in exit_thread()
From: "Kevin D. Kissell" <kevink@mips.com>
Date: Thu, 6 Jun 2002 20:21:15 +0200
References: <Pine.LNX.4.44.0206061657510.25647-100000@coplin19.mips.com>
Sender: owner-linux-mips@oss.sgi.com
It's been a while since I worked on the code,
but I'm not sure why last_task_used_math
needs to be cleared if there is no FPU.
The way the FPU emulator was integrated,
the FPU register storage *is* the thread
context, so if there is no FPU, there was no 
FPU context switching, lazy or otherwise.  
Sounds like someone broke this.

Beyond that, the CFC1 instruction is presumably
there because in the R4000 (at least) it is specified
as the means to force the FP pipeline to drain
before the context switch.  I would suppose this
would be done in Linux to avoid mis-attribution
of FP exceptions. (See chapter 6 of the R4000 
User's manual, page 160 in the Second Edition).

            Kevin K.

----- Original Message ----- 
From: "Kjeld Borch Egevang" <kjelde@mips.com>
To: "linux-mips mailing list" <linux-mips@oss.sgi.com>
Sent: Thursday, June 06, 2002 5:06 PM
Subject: Float crash. Fix in exit_thread()


> I'm running on a system with no FPU. Now, I've got a program do_float 
> which seems to work fine. But if I enter:
> 
> /bin/echo hello; ./do_float
> 
> it terminates with a bus error or FP error. The bug is in exit_thread(). 
> Can anyone explain to me, what good the "cfc1 $0,$31" does?
> 
> 
> Here is the patch:
> 
> RCS file: /cvs/linux/arch/mips/kernel/process.c,v
> retrieving revision 1.36
> diff -u -r1.36 process.c
> --- process.c   2002/05/29 18:36:28     1.36
> +++ process.c   2002/06/06 14:51:32
> @@ -54,9 +54,11 @@
>  void exit_thread(void)
>  {
>         /* Forget lazy fpu state */
> -       if (last_task_used_math == current && mips_cpu.options & 
> MIPS_CPU_FPU) {
> -               __enable_fpu();
> -               __asm__ __volatile__("cfc1\t$0,$31");
> +       if (last_task_used_math == current) {
> +               if (mips_cpu.options & MIPS_CPU_FPU) {
> +                       __enable_fpu();
> +                       __asm__ __volatile__("cfc1\t$0,$31");
> +               }
>                 last_task_used_math = NULL;
>         }
>  }
> @@ -64,9 +66,11 @@
>  void flush_thread(void)
>  {
>         /* Forget lazy fpu state */
> -       if (last_task_used_math == current && mips_cpu.options & 
> MIPS_CPU_FPU) {
> -               __enable_fpu();
> -               __asm__ __volatile__("cfc1\t$0,$31");
> +       if (last_task_used_math == current) {
> +               if (mips_cpu.options & MIPS_CPU_FPU) {
> +                       __enable_fpu();
> +                       __asm__ __volatile__("cfc1\t$0,$31");
> +               }
>                 last_task_used_math = NULL;
>         }
>  }
> 
> 
> 
> /Kjeld
> 
> 
> -- 
> _    _ ____  ___                       Mailto:kjelde@mips.com
> |\  /|||___)(___    MIPS Denmark       Direct: +45 44 86 55 85
> | \/ |||    ____)   Lautrupvang 4 B    Switch: +45 44 86 55 55
>   TECHNOLOGIES      DK-2750 Ballerup   Fax...: +45 44 86 55 56
>                     Denmark            http://www.mips.com/
> 
> 


<Prev in Thread] Current Thread [Next in Thread>