All of lore.kernel.org
 help / color / mirror / Atom feed
From: Carsten Langgaard <carstenl@mips.com>
To: Jun Sun <jsun@mvista.com>
Cc: linux-mips@oss.sgi.com
Subject: Re: an old FPU context corruption problem when signal happens
Date: Thu, 20 Dec 2001 08:58:51 +0100	[thread overview]
Message-ID: <3C219A3B.6DA93A75@mips.com> (raw)
In-Reply-To: 3C21390A.FA23978D@mvista.com

Are you sure this hasn't been fix in the latest sources (2.4.16) ?
I have send a patch to Ralf, which I believe solves a similar problem as you describe below.

Ralf have you applied the patch ?

/Carsten

Jun Sun wrote:

> This is an incomplete patch, attempting to fix an old fix FPU context
> corruption problem with signal happens.
>
> The following scenario would cause many problems with current code:
>
> 1. process A runs and uses FPU
> 2. Process A is switched out; Process B runs and uses FPU
> 3. Process A runs again, but have not used FPU this time around
> 4. Process A receives a signal.
> 5. Process A's signal handler runs and uses FPU
> 6. Process B runs again and uses FPU.
>
> At step 4, we have last_task_used_fpu being B, current->used_math being 1.
> The current code would save B's FPU context to A's sc structure, but
> does not mark owned_fp bits.
>
> At step 5, when A's sig handler first time uses FPU, FPU is enabled again.
>
> At step 6, when B tries to use FPU again, a lazy fpu switch happens.  The
> current FPU regs are stored into A's thread strucutre, effectively eraseing
> previously stored A's FPU context before the sig handler starts.
>
> In addition, B finds its FPU reg values totally bogus when they are loaded
> from B's thread structure, because the FPU regs were saved there.  (See
> step 4).
>
> This patch is meant for concept debugging.  But it should be easy
> to complete it:
>
> 1. support the two copy_fpu_context function.  (note, need to differentiate
> between CPU_HAS_FPU and !CPU_HAS_FPU cases)
> 2. perhaps change ->sc_ownedfp to ->sc_used_fpu, which is really what
> this flag means now.
>
> Any comments?
>
> Jun
>
>   ------------------------------------------------------------------------
>
> This is an incomplete patch, attempting to fix an old fix FPU context
> corruption problem with signal happens.
>
> The following scenario would cause many problems with current code:
>
> 1. process A runs and uses FPU
> 2. Process A is switched out; Process B runs and uses FPU
> 3. Process A runs again, but have not used FPU this time around
> 4. Process A receives a signal.
> 5. Process A's signal handler runs and uses FPU
> 6. Process B runs again and uses FPU.
>
> At step 4, we have last_task_used_fpu being B, current->used_math being 1.
> The current code would save B's FPU context to A's sc structure, but
> does not mark owned_fp bits.
>
> At step 5, when A's sig handler first time uses FPU, FPU is enabled again.
>
> At step 6, when B tries to use FPU again, a lazy fpu switch happens.  The
> current FPU regs are stored into A's thread strucutre, effectively eraseing
> previously stored A's FPU context before the sig handler starts.
>
> In addition, B finds its FPU reg values totally bogus when they are loaded
> from B's thread structure, because the FPU regs were saved there.  (See
> step 4).
>
> This patch is meant for concept debugging.  But it should be easy
> to complete it:
>
> 1. support the two copy_fpu_context function.  (note, need to differentiate
> between CPU_HAS_FPU and !CPU_HAS_FPU cases)
> 2. perhaps change ->sc_ownedfp to ->sc_used_fpu, which is really what
> this flag means now.
>
> Any comments?
>
> Jun
>
> diff -Nru linux.link/arch/mips/kernel/signal.c.orig linux.link/arch/mips/kernel/signal.c
> --- linux.link/arch/mips/kernel/signal.c.orig   Tue Nov 27 11:03:02 2001
> +++ linux.link/arch/mips/kernel/signal.c        Wed Dec 19 16:28:08 2001
> @@ -222,8 +222,20 @@
>
>         err |= __get_user(owned_fp, &sc->sc_ownedfp);
>         if (owned_fp) {
> -               err |= restore_fp_context(sc);
> -               last_task_used_math = current;
> +               if ((last_task_used_match == NULL) || (last_task_used_math == current)) {
> +                       /* if nobody owns FPU, or sig handler owns it,
> +                        * we just restore FPU regs from sc to hardware */
> +                       err |= restore_fp_context(sc);
> +                       last_task_used_math = current;
> +                       enable_fpu();
> +               } else {
> +                       /* we copy FPU values from sc to task structure */
> +                       err |= copy_fpu_context_from_sigcontext(current, sc);
> +                       disable_fpu();
> +               }
> +
> +               /* in either case, we need to set the used flag */
> +               current->used_math = 1;
>         }
>
>         return err;
> @@ -352,13 +364,25 @@
>         err |= __put_user(regs->cp0_cause, &sc->sc_cause);
>         err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
>
> -       owned_fp = (current == last_task_used_math);
> -       err |= __put_user(owned_fp, &sc->sc_ownedfp);
> +       /* if we ever used FPU, we need to get FPU regs to sc */
> +       if (current->used_math) {
> +
> +               if (current == last_task_used_math) {
> +                       /* if we own FPU now, just save fpu to sc directly */
> +                       enable_fpu();
> +                       err |= save_fp_context(sc);
> +               } else {
> +                       /* otherwise, we need copy fpu regs from current task
> +                        * structure to sc structre.
> +                        */
> +                       err |= copy_fpu_context_to_sigcontext(current, sc);
> +               }
> +
> +               /* put remember that we have valid FPU regs in sc */
> +               err |= __put_user(current->used_math, &sc->sc_ownedfp);
>
> -       if (current->used_math) {       /* fp is active.  */
> -               enable_fpu();
> -               err |= save_fp_context(sc);
> -               last_task_used_math = NULL;
> +               /* we now pretend we have never used FPU before we start sig
> +                * handler */
>                 regs->cp0_status &= ~ST0_CU1;
>                 current->used_math = 0;
>         }

--
_    _ ____  ___   Carsten Langgaard   Mailto:carstenl@mips.com
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
                   Denmark             http://www.mips.com

  reply	other threads:[~2001-12-20  8:59 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-12-20  1:04 an old FPU context corruption problem when signal happens Jun Sun
2001-12-20  7:58 ` Carsten Langgaard [this message]
2001-12-20 17:16   ` Jun Sun
2001-12-25  6:41   ` Ralf Baechle
2001-12-25  6:51     ` Ralf Baechle
2001-12-27 10:53     ` Carsten Langgaard
2002-01-02  4:34       ` Ralf Baechle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C219A3B.6DA93A75@mips.com \
    --to=carstenl@mips.com \
    --cc=jsun@mvista.com \
    --cc=linux-mips@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.