CLONE_THREAD does not have the guarantee of a true fork to inherit all state. Especially the FPU state is meaningless for CLONE_THREAD. Just wipe out the minimal required state so restore on return to user space let's the thread start with a clean FPU. Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> --- arch/x86/include/asm/fpu/internal.h | 2 +- arch/x86/kernel/fpu/core.c | 8 +++++--- arch/x86/kernel/process.c | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -34,7 +34,7 @@ extern int fpu__exception_code(struct f extern void fpu_sync_fpstate(struct fpu *fpu); /* Clone and exit operations */ -extern int fpu_clone(struct task_struct *dst); +extern int fpu_clone(struct task_struct *dst, unsigned long clone_flags); extern void fpu_flush_thread(void); /* --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -257,7 +257,7 @@ void fpstate_init(union fpregs_state *st EXPORT_SYMBOL_GPL(fpstate_init); /* Clone current's FPU state on fork */ -int fpu_clone(struct task_struct *dst) +int fpu_clone(struct task_struct *dst, unsigned long clone_flags) { struct fpu *src_fpu = ¤t->thread.fpu; struct fpu *dst_fpu = &dst->thread.fpu; @@ -276,9 +276,11 @@ int fpu_clone(struct task_struct *dst) /* * No FPU state inheritance for kernel threads and IO - * worker threads. + * worker threads. Neither CLONE_THREAD needs a copy + * of the FPU state. */ - if (dst->flags & (PF_KTHREAD | PF_IO_WORKER)) { + if (clone_flags & CLONE_THREAD || + dst->flags & (PF_KTHREAD | PF_IO_WORKER)) { /* Clear out the minimal state */ memcpy(&dst_fpu->state, &init_fpstate, init_fpstate_copy_size()); --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -154,7 +154,7 @@ int copy_thread(unsigned long clone_flag frame->flags = X86_EFLAGS_FIXED; #endif - fpu_clone(p); + fpu_clone(p, clone_flags); /* Kernel thread ? */ if (unlikely(p->flags & PF_KTHREAD)) {