aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-01-11 06:11:39 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-12 04:09:29 -0500
commit5388fb1025443ec223ba556b10efc4c5f83f8682 (patch)
treeb14832a8886bd254533f226263a2047545c57805 /include
parent593195f9b2309693f27b402f34573f7920b82c3e (diff)
[PATCH] powerpc: Avoid potential FP corruption with preempt and UP
Heikki Lindholm pointed out that there was a potential race with the lazy CPU state (FP, VR, EVR) stuff if preempt is enabled. The race is that in the process of restoring FP state on sigreturn, the task gets preempted by a user task that wants to use the FPU. It will take an FP unavailable exception, which will write the current FPU state to the thread_struct, overwriting the values which sigreturn has stored. Note that this can only happen on UP since we don't implement lazy CPU state on SMP. The fix is to flush the lazy CPU state before updating the thread_struct. To do this we re-use the flush_lazy_cpu_state() function from process.c. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-powerpc/system.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 0c58e32a9570..4c888303e85b 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -133,6 +133,14 @@ extern int fix_alignment(struct pt_regs *);
133extern void cvt_fd(float *from, double *to, struct thread_struct *thread); 133extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
134extern void cvt_df(double *from, float *to, struct thread_struct *thread); 134extern void cvt_df(double *from, float *to, struct thread_struct *thread);
135 135
136#ifndef CONFIG_SMP
137extern void discard_lazy_cpu_state(void);
138#else
139static inline void discard_lazy_cpu_state(void)
140{
141}
142#endif
143
136#ifdef CONFIG_ALTIVEC 144#ifdef CONFIG_ALTIVEC
137extern void flush_altivec_to_thread(struct task_struct *); 145extern void flush_altivec_to_thread(struct task_struct *);
138#else 146#else