lkml.org 
[lkml]   [2004]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] PPC/PPC64: Fix FP state corruption on UP
Unfortunately the patch Ben sent last week to fix a bug in the saving
and restoring of floating-point and altivec context across signal
handlers introduced another bug, which tends to corrupt the FP and
altivec contexts of other tasks. This patch fixes the problem for
both ppc32 and ppc64. Please apply.

Signed-off-by: Paul Mackerras <paulus@samba.org>

diff -urN linux-2.5/arch/ppc/kernel/signal.c test/arch/ppc/kernel/signal.c
--- linux-2.5/arch/ppc/kernel/signal.c 2004-10-20 08:16:36.000000000 +1000
+++ test/arch/ppc/kernel/signal.c 2004-10-27 14:29:48.494955208 +1000
@@ -290,7 +290,7 @@

/* force the process to reload the FP registers from
current->thread when it next does FP instructions */
- regs->msr &= ~MSR_FP;
+ regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
if (__copy_from_user(current->thread.fpr, &sr->mc_fregs,
sizeof(sr->mc_fregs)))
return 1;
@@ -330,9 +330,14 @@
#endif /* CONFIG_SPE */

#ifndef CONFIG_SMP
- last_task_used_math = NULL;
- last_task_used_altivec = NULL;
- last_task_used_spe = NULL;
+ preempt_disable();
+ if (last_task_used_math == current)
+ last_task_used_math = NULL;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = NULL;
+ if (last_task_used_spe == current)
+ last_task_used_spe = NULL;
+ preempt_enable();
#endif
return 0;
}
diff -urN linux-2.5/arch/ppc64/kernel/signal.c test/arch/ppc64/kernel/signal.c
--- linux-2.5/arch/ppc64/kernel/signal.c 2004-10-20 08:16:36.000000000 +1000
+++ test/arch/ppc64/kernel/signal.c 2004-10-27 14:31:57.301942136 +1000
@@ -224,8 +224,12 @@
#endif /* CONFIG_ALTIVEC */

#ifndef CONFIG_SMP
- last_task_used_math = NULL;
- last_task_used_altivec = NULL;
+ preempt_disable();
+ if (last_task_used_math == current)
+ last_task_used_math = NULL;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = NULL;
+ preempt_enable();
#endif
/* Force reload of FP/VEC */
regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC);
diff -urN linux-2.5/arch/ppc64/kernel/signal32.c test/arch/ppc64/kernel/signal32.c
--- linux-2.5/arch/ppc64/kernel/signal32.c 2004-10-20 08:16:36.000000000 +1000
+++ test/arch/ppc64/kernel/signal32.c 2004-10-27 14:32:45.086999136 +1000
@@ -235,8 +235,12 @@
#endif /* CONFIG_ALTIVEC */

#ifndef CONFIG_SMP
- last_task_used_math = NULL;
- last_task_used_altivec = NULL;
+ preempt_disable();
+ if (last_task_used_math == current)
+ last_task_used_math = NULL;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = NULL;
+ preempt_enable();
#endif
return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 14:07    [W:0.092 / U:0.484 seconds]
©2003-2014 Jasper Spaans. Advertise on this site