From ffb3feb73f89a34459b84f229a9ac699a589ed8f Mon Sep 17 00:00:00 2001 From: Michael Edwards Date: Sat, 24 Apr 2010 20:53:38 -0700 Subject: [PATCH] x86,fpu: Protect FPU context cleanup against SSE2 in ISRs Clean up task FPU state thoroughly during exec() and process tear-down, and lock out local IRQs while doing it, so that SSE2 instructions in ISRs don't cause fxsave/fxrstor to/from a null pointer. (They still need to be guarded with kernel_fpu_(begin|end), of course.) Signed-off-by: Michael Edwards --- arch/x86/kernel/process.c | 10 ++++++++++ arch/x86/kernel/process_32.c | 4 +--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 876e918..bde7d09 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -8,6 +8,7 @@ #include #include #include +#include unsigned long idle_halt; EXPORT_SYMBOL(idle_halt); @@ -31,12 +32,21 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) return 0; } +/* + * Locks out local IRQs while clearing FPU state and + * related task properties, so that ISRs can use SSE2. + */ void free_thread_xstate(struct task_struct *tsk) { + local_irq_disable(); if (tsk->thread.xstate) { + tsk->fpu_counter = 0; + clear_stopped_child_used_math(tsk); + __clear_fpu(tsk); kmem_cache_free(task_xstate_cachep, tsk->thread.xstate); tsk->thread.xstate = NULL; } + local_irq_enable(); } void free_thread_info(struct thread_info *ti) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 31f40b2..7122160 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -294,9 +294,7 @@ void flush_thread(void) /* * Forget coprocessor state.. */ - tsk->fpu_counter = 0; - clear_fpu(tsk); - clear_used_math(); + free_thread_xstate(tsk); } void release_thread(struct task_struct *dead_task) -- 1.7.0