* an old FPU context corruption problem when signal happens
@ 2001-12-20 1:04 Jun Sun
2001-12-20 7:58 ` Carsten Langgaard
0 siblings, 1 reply; 7+ messages in thread
From: Jun Sun @ 2001-12-20 1:04 UTC (permalink / raw)
To: linux-mips
[-- Attachment #1: Type: text/plain, Size: 1388 bytes --]
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
[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 3333 bytes --]
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;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: an old FPU context corruption problem when signal happens
2001-12-20 1:04 an old FPU context corruption problem when signal happens Jun Sun
@ 2001-12-20 7:58 ` Carsten Langgaard
2001-12-20 17:16 ` Jun Sun
2001-12-25 6:41 ` Ralf Baechle
0 siblings, 2 replies; 7+ messages in thread
From: Carsten Langgaard @ 2001-12-20 7:58 UTC (permalink / raw)
To: Jun Sun; +Cc: linux-mips
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: an old FPU context corruption problem when signal happens
2001-12-20 7:58 ` Carsten Langgaard
@ 2001-12-20 17:16 ` Jun Sun
2001-12-25 6:41 ` Ralf Baechle
1 sibling, 0 replies; 7+ messages in thread
From: Jun Sun @ 2001-12-20 17:16 UTC (permalink / raw)
To: Carsten Langgaard; +Cc: linux-mips
On Thu, Dec 20, 2001 at 08:58:51AM +0100, Carsten Langgaard wrote:
> 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 ?
>
Apparently not. My patch is against the latest 2.4.16 tree,
which should also applies to 2.5 tree.
BTW, does my fix look reasonable? What is your fix? There are several
places which are tricky.
Jun
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: an old FPU context corruption problem when signal happens
2001-12-20 7:58 ` Carsten Langgaard
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
1 sibling, 2 replies; 7+ messages in thread
From: Ralf Baechle @ 2001-12-25 6:41 UTC (permalink / raw)
To: Carsten Langgaard; +Cc: Jun Sun, linux-mips
On Thu, Dec 20, 2001 at 08:58:51AM +0100, Carsten Langgaard wrote:
> 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 ?
Well, I applied it but it's really broken as something can be. Just an
example:
+ /*
+ * FPU emulator may have it's own trampoline active just
+ * above the user stack, 16-bytes before the next lowest
+ * 16 byte boundary. Try to avoid trashing it.
+ */
+ sp -= 32;
So the whole thing needs some overhaul.
Ralf
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: an old FPU context corruption problem when signal happens
2001-12-25 6:41 ` Ralf Baechle
@ 2001-12-25 6:51 ` Ralf Baechle
2001-12-27 10:53 ` Carsten Langgaard
1 sibling, 0 replies; 7+ messages in thread
From: Ralf Baechle @ 2001-12-25 6:51 UTC (permalink / raw)
To: Carsten Langgaard; +Cc: linux-mips
On Tue, Dec 25, 2001 at 04:41:25AM -0200, Ralf Baechle wrote:
> > 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 ?
>
> Well, I applied it but it's really broken as something can be. Just an
> example:
>
> + /*
> + * FPU emulator may have it's own trampoline active just
> + * above the user stack, 16-bytes before the next lowest
> + * 16 byte boundary. Try to avoid trashing it.
> + */
> + sp -= 32;
>
> So the whole thing needs some overhaul.
Btw, the whole fp trampoline thing will have to die anyway. Virtually
indexed i-caches on some new types of SMP are making them even more
expensive then they already are.
Ralf
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: an old FPU context corruption problem when signal happens
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
1 sibling, 1 reply; 7+ messages in thread
From: Carsten Langgaard @ 2001-12-27 10:53 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Jun Sun, linux-mips
Ralf Baechle wrote:
> On Thu, Dec 20, 2001 at 08:58:51AM +0100, Carsten Langgaard wrote:
>
> > 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 ?
>
> Well, I applied it but it's really broken as something can be. Just an
> example:
>
> + /*
> + * FPU emulator may have it's own trampoline active just
> + * above the user stack, 16-bytes before the next lowest
> + * 16 byte boundary. Try to avoid trashing it.
> + */
> + sp -= 32;
>
> So the whole thing needs some overhaul.
>
You are welcome to find a better way of handling a non-fpu instruction in the
delay slot of the fpu-branch instruction.
But until someone find a better solution (that works, in all situation), I
think we need this patch.
> Ralf
--
_ _ ____ ___ 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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: an old FPU context corruption problem when signal happens
2001-12-27 10:53 ` Carsten Langgaard
@ 2002-01-02 4:34 ` Ralf Baechle
0 siblings, 0 replies; 7+ messages in thread
From: Ralf Baechle @ 2002-01-02 4:34 UTC (permalink / raw)
To: Carsten Langgaard; +Cc: Jun Sun, linux-mips
On Thu, Dec 27, 2001 at 11:53:00AM +0100, Carsten Langgaard wrote:
> You are welcome to find a better way of handling a non-fpu instruction in the
> delay slot of the fpu-branch instruction.
> But until someone find a better solution (that works, in all situation), I
> think we need this patch.
I could live with your solution if we'd be living in uniprocessor-land
only. Well, that time is over now ...
Ralf
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2002-01-02 5:34 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-12-20 1:04 an old FPU context corruption problem when signal happens Jun Sun
2001-12-20 7:58 ` Carsten Langgaard
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
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.