x86/fpu changes for v3.5
Subsystems (19)
Linus,
Please pull the latest x86-fpu-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-fpu-for-linus
HEAD: 1dcc8d7ba235a316a056f993e88f0d18b92c60d9 x86, fpu: drop the fpu state during thread exit
This tree streamlines further aspects of FPU handling by eliminating the prepare_to_copy() complication and moving that logic to arch_dup_task_struct(). It also fixes the FPU dumps in threaded core dumps, removes and old (and now invalid) assumption plus micro-optimizes the exit path by avoiding an FPU save for dead tasks.
out-of-topic modifications in x86-fpu-for-linus:
------------------------------------------------arch/alpha/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_coarch/arm/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_coarch/avr32/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/blackfin/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_co
arch/c6x/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/cris/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/frv/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/frv/kernel/process.c # 55ccf3f: fork: move the real prepare_to_co arch/h8300/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/hexagon/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_co arch/ia64/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/m32r/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/m68k/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co
arch/microblaze/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_co arch/mips/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/mn10300/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_coarch/mn10300/kernel/process.c # 55ccf3f: fork: move the real prepare_to_co
arch/openrisc/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_co arch/parisc/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_co arch/powerpc/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_coarch/powerpc/kernel/process.c # 55ccf3f: fork: move the real prepare_to_coarch/s390/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/score/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/sh/include/asm/processor_32.h # 55ccf3f: fork: move the real prepare_to_co arch/sh/include/asm/processor_64.h # 55ccf3f: fork: move the real prepare_to_coarch/sh/kernel/process.c # 55ccf3f: fork: move the real prepare_to_coarch/sh/kernel/process_32.c # 55ccf3f: fork: move the real prepare_to_co
arch/sparc/include/asm/processor_32.h# 55ccf3f: fork: move the real prepare_to_co arch/sparc/include/asm/processor_64.h# 55ccf3f: fork: move the real prepare_to_co arch/tile/include/asm/processor.h # 55ccf3f: fork: move the real prepare_to_co arch/um/include/asm/processor-generic.h# 55ccf3f: fork: move the real prepare_to_co arch/unicore32/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_co arch/xtensa/include/asm/processor.h# 55ccf3f: fork: move the real prepare_to_coarch/xtensa/kernel/process.c # 55ccf3f: fork: move the real prepare_to_cofs/exec.c # 11aeca0: coredump: ensure the fpu state is
Thanks,
Ingo
------------------>
Suresh Siddha (4):
fork: move the real prepare_to_copy() users to arch_dup_task_struct()
coredump: ensure the fpu state is flushed for proper multi-threaded core dump x86, xsave: remove thread_has_fpu() bug check in __sanitize_i387_state() x86, fpu: drop the fpu state during thread exit
arch/alpha/include/asm/processor.h | 3 --- arch/arm/include/asm/processor.h | 3 --- arch/avr32/include/asm/processor.h | 3 --- arch/blackfin/include/asm/processor.h | 2 -- arch/c6x/include/asm/processor.h | 3 --- arch/cris/include/asm/processor.h | 4 ---- arch/frv/include/asm/processor.h | 2 -- arch/frv/kernel/process.c | 11 ----------- arch/h8300/include/asm/processor.h | 2 -- arch/hexagon/include/asm/processor.h | 7 ------- arch/ia64/include/asm/processor.h | 3 --- arch/m32r/include/asm/processor.h | 2 -- arch/m68k/include/asm/processor.h | 3 --- arch/microblaze/include/asm/processor.h | 1 - arch/mips/include/asm/processor.h | 3 --- arch/mn10300/include/asm/processor.h | 3 --- arch/mn10300/kernel/process.c | 10 ++++++---- arch/openrisc/include/asm/processor.h | 4 ---- arch/parisc/include/asm/processor.h | 3 --- arch/powerpc/include/asm/processor.h | 3 --- arch/powerpc/kernel/process.c | 19 +++++++++++-------- arch/s390/include/asm/processor.h | 3 --- arch/score/include/asm/processor.h | 1 - arch/sh/include/asm/processor_32.h | 3 --- arch/sh/include/asm/processor_64.h | 1 - arch/sh/kernel/process.c | 7 +++++++ arch/sh/kernel/process_32.c | 9 --------- arch/sparc/include/asm/processor_32.h | 3 --- arch/sparc/include/asm/processor_64.h | 3 --- arch/tile/include/asm/processor.h | 3 --- arch/um/include/asm/processor-generic.h | 5 ----- arch/unicore32/include/asm/processor.h | 3 --- arch/x86/include/asm/processor.h | 3 --- arch/x86/kernel/process.c | 25 +++++++++++++++++++------ arch/x86/kernel/process_32.c | 9 --------- arch/x86/kernel/process_64.c | 9 --------- arch/x86/kernel/xsave.c | 2 -- arch/xtensa/include/asm/processor.h | 3 --- arch/xtensa/kernel/process.c | 9 ++++++--- fs/exec.c | 15 ++++++++++++++- kernel/fork.c | 2 -- 41 files changed, 63 insertions(+), 149 deletions(-)
arch/alpha/include/asm/processor.h +0 -3
@@ -49,9 +49,6 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long);/* Free all resources held by a thread. */ extern void release_thread (struct task_struct *); -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -/* Create a kernel thread without removing it from tasklists. */ extern long kernel_thread (int (*fn)(void *),void *arg,unsigned long flags);
arch/arm/include/asm/processor.h +0 -3
@@ -77,9 +77,6 @@ struct task_struct;/* Free all resources held by a thread. */ extern void release_thread (struct task_struct *); -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -unsigned long get_wchan (struct task_struct *p);#if __LINUX_ARM_ARCH__ ==6 || defined(CONFIG_ARM_ERRATA_754327 )
arch/avr32/include/asm/processor.h +0 -3
@@ -145,9 +145,6 @@ extern void release_thread(struct task_struct *);/* Create a kernel thread without removing it from tasklists */ extern int kernel_thread (int (*fn)(void *),void *arg,unsigned long flags); -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while(0) -/* Return saved PC of a blocked thread */ #define thread_saved_pc (tsk) ((tsk)->thread.cpu_context.pc)
arch/blackfin/include/asm/processor.h +0 -2
@@ -75,8 +75,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -#define prepare_to_copy (tsk) do { } while (0) -extern int kernel_thread (int (*fn) (void *),void *arg,unsigned long flags);/*
arch/c6x/include/asm/processor.h +0 -3
@@ -92,9 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags);#define copy_segments (tsk, mm) do { } while (0)
arch/cris/include/asm/processor.h +0 -4
@@ -50,10 +50,6 @@ struct task_struct;#define task_pt_regs (task) user_regs(task_thread_info(task))#define current_regs () task_pt_regs(current) -static inline void prepare_to_copy (struct task_struct *tsk) -{ -} -extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags);unsigned long get_wchan (struct task_struct *p);
arch/frv/include/asm/processor.h +0 -2
@@ -103,8 +103,6 @@ do { \ __frame->sp = (_usp); \ }while (0 ) -extern void prepare_to_copy(struct task_struct *tsk); -/* Free all resources held by a thread. */ static inline void release_thread(struct task_struct *dead_task) {
arch/frv/kernel/process.c +0 -11
@@ -180,17 +180,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,return do_fork (clone_flags, newsp, __frame,0 , parent_tidptr, child_tidptr); }/* end sys_clone() */ -/*****************************************************************************/ -/* -* This gets called before we allocate a new thread and copy -* the current task into it. -*/ -void prepare_to_copy (struct task_struct *tsk) -{ -//unlazy_fpu(tsk); -}/* end prepare_to_copy() */ - -/*****************************************************************************/ /* * set up the kernel stack and exception frames for a new process */
arch/h8300/include/asm/processor.h +0 -2
@@ -109,8 +109,6 @@ static inline void release_thread(struct task_struct *dead_task)extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags); -#define prepare_to_copy (tsk) do { } while (0) -/* * Free current thread data structures etc.. */
arch/hexagon/include/asm/processor.h +0 -7
@@ -59,13 +59,6 @@ struct thread_struct {#define cpu_relax () __vmyield()/* -* "Unlazying all lazy status" occurs here. -*/ -static inline void prepare_to_copy (struct task_struct *tsk) -{ -} - -/* * Decides where the kernel will search for a free chunk of vm space during * mmaps. * See also arch_get_unmapped_area.
arch/ia64/include/asm/processor.h +0 -3
@@ -343,9 +343,6 @@ struct task_struct;*/ #define release_thread (dead_task) -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -/* * This is the mechanism for creating a new kernel thread. *
arch/m32r/include/asm/processor.h +0 -2
@@ -118,8 +118,6 @@ struct mm_struct;/* Free all resources held by a thread. */ extern void release_thread (struct task_struct *); -#define prepare_to_copy (tsk) do { } while (0) -/* * create a kernel thread without removing it from tasklists */
arch/m68k/include/asm/processor.h +0 -3
@@ -153,9 +153,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags);/*
arch/microblaze/include/asm/processor.h +0 -1
@@ -23,7 +23,6 @@ extern const struct seq_operations cpuinfo_op;# define cpu_relax () barrier()# define cpu_sleep () do {} while (0) -# define prepare_to_copy (tsk) do {} while (0)#define task_pt_regs (tsk) \ (((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1)
arch/mips/include/asm/processor.h +0 -3
@@ -310,9 +310,6 @@ struct task_struct;/* Free all resources held by a thread. */ #define release_thread (thread) do { } while(0) -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -extern long kernel_thread (int (*fn)(void *),void * arg,unsigned long flags);extern unsigned long thread_saved_pc (struct task_struct *tsk);
arch/mn10300/include/asm/processor.h +0 -3
@@ -139,9 +139,6 @@ static inline void start_thread(struct pt_regs *regs,/* Free all resources held by a thread. */ extern void release_thread (struct task_struct *); -/* Prepare to copy thread state - unlazy all lazy status */ -extern void prepare_to_copy (struct task_struct *tsk); -/* * create a kernel thread without removing it from tasklists */
arch/mn10300/kernel/process.c +6 -4
@@ -208,12 +208,14 @@ void copy_segments(struct task_struct *p, struct mm_struct *new_mm) }/* -* this gets called before we allocate a new thread and copy the current task -* into it so that we can store lazy state into memory +* this gets called so that we can store lazy state into memory and copy the +* current task into the new thread. */ -void prepare_to_copy (struct task_struct *tsk) +int arch_dup_task_struct (struct task_struct *dst,struct task_struct *src) { -unlazy_fpu (tsk); +unlazy_fpu (src); + *dst = *src; +return 0 ; }/*
arch/openrisc/include/asm/processor.h +0 -4
@@ -72,10 +72,6 @@ struct thread_struct {#define task_pt_regs (task) user_regs(task_thread_info(task))#define current_regs () user_regs(current_thread_info()) -extern inline void prepare_to_copy (struct task_struct *tsk) -{ -} -#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack)#define INIT_THREAD { }
arch/parisc/include/asm/processor.h +0 -3
@@ -328,9 +328,6 @@ struct mm_struct;extern void release_thread (struct task_struct *);extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags); -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -extern void map_hpux_gateway_page (struct task_struct *tsk,struct mm_struct *mm);extern unsigned long get_wchan (struct task_struct *p);
arch/powerpc/include/asm/processor.h +0 -3
@@ -74,9 +74,6 @@ struct task_struct;void start_thread (struct pt_regs *regs,unsigned long fdptr,unsigned long sp);void release_thread (struct task_struct *); -/* Prepare to copy thread state - unlazy all lazy status */ -extern void prepare_to_copy (struct task_struct *tsk); -/* Create a new kernel thread. */ extern long kernel_thread (int (*fn)(void *),void *arg,unsigned long flags);
arch/powerpc/kernel/process.c +11 -8
@@ -711,18 +711,21 @@ release_thread(struct task_struct *t) }/* -* This gets called before we allocate a new thread and copy -* the current task into it. +* this gets called so that we can store coprocessor state into memory and +* copy the current task into the new thread. */ -void prepare_to_copy (struct task_struct *tsk) +int arch_dup_task_struct (struct task_struct *dst,struct task_struct *src) { -flush_fp_to_thread (current); -flush_altivec_to_thread (current); -flush_vsx_to_thread (current); -flush_spe_to_thread (current); +flush_fp_to_thread (src); +flush_altivec_to_thread (src); +flush_vsx_to_thread (src); +flush_spe_to_thread (src);#ifdef CONFIG_HAVE_HW_BREAKPOINT -flush_ptrace_hw_breakpoint (tsk); +flush_ptrace_hw_breakpoint (src);#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + + *dst = *src; +return 0 ; }/*
arch/s390/include/asm/processor.h +0 -3
@@ -141,9 +141,6 @@ struct seq_file;extern void release_thread (struct task_struct *);extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags); -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -/* * Return saved PC of a blocked thread. */
arch/score/include/asm/processor.h +0 -1
@@ -26,7 +26,6 @@ extern unsigned long get_wchan(struct task_struct *p);#define cpu_relax () barrier()#define release_thread (thread) do {} while (0) -#define prepare_to_copy (tsk) do {} while (0)/* * User space process size: 2GB. This is hardcoded into a few places,
arch/sh/include/asm/processor_32.h +0 -3
@@ -126,9 +126,6 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned lo/* Free all resources held by a thread. */ extern void release_thread (struct task_struct *); -/* Prepare to copy thread state - unlazy all lazy status */ -void prepare_to_copy (struct task_struct *tsk); -/* * create a kernel thread without removing it from tasklists */
arch/sh/include/asm/processor_64.h +0 -1
@@ -172,7 +172,6 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);#define copy_segments (p, mm) do { } while (0)#define release_segments (mm) do { } while (0)#define forget_segments () do { } while (0) -#define prepare_to_copy (tsk) do { } while (0)/* * FPU lazy state save handling. */
arch/sh/kernel/process.c +7 -0
@@ -6,8 +6,15 @@struct kmem_cache *task_xstate_cachep =NULL ;unsigned int xstate_size; +/* +* this gets called so that we can store lazy state into memory and copy the +* current task into the new thread. +*/ int arch_dup_task_struct (struct task_struct *dst,struct task_struct *src) { +#ifdef CONFIG_SUPERH32 +unlazy_fpu (src,task_pt_regs (src)); +#endif *dst = *src;if (src->thread.xstate) {
arch/sh/kernel/process_32.c +0 -9
@@ -155,15 +155,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) }EXPORT_SYMBOL (dump_fpu); -/* -* This gets called before we allocate a new thread and copy -* the current task into it. -*/ -void prepare_to_copy (struct task_struct *tsk) -{ -unlazy_fpu (tsk,task_pt_regs (tsk)); -} - asmlinkage void ret_from_fork(void); int copy_thread(unsigned long clone_flags, unsigned long usp,
arch/sparc/include/asm/processor_32.h +0 -3
@@ -109,9 +109,6 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc,#define release_thread (tsk) do { } while(0)extern pid_t kernel_thread (int (*fn)(void *),void * arg,unsigned long flags); -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -extern unsigned long get_wchan (struct task_struct *);#define task_pt_regs (tsk) ((tsk)->thread.kregs)
arch/sparc/include/asm/processor_64.h +0 -3
@@ -186,9 +186,6 @@ do { \/* Free all resources held by a thread. */ #define release_thread (tsk) do { } while (0) -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -extern pid_t kernel_thread (int (*fn)(void *),void * arg,unsigned long flags);extern unsigned long get_wchan (struct task_struct *task);
arch/tile/include/asm/processor.h +0 -3
@@ -210,9 +210,6 @@ static inline void release_thread(struct task_struct *dead_task)/* Nothing for now */ } -/* Prepare to copy thread state - unlazy all lazy status. */ -#define prepare_to_copy (tsk) do { } while (0) -extern int kernel_thread (int (*fn)(void *),void *arg,unsigned long flags);extern int do_work_pending (struct pt_regs *regs,u32 flags);
arch/um/include/asm/processor-generic.h +0 -5
@@ -76,11 +76,6 @@ static inline void release_thread(struct task_struct *task)extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags); -static inline void prepare_to_copy (struct task_struct *tsk) -{ -} - -extern unsigned long thread_saved_pc (struct task_struct *t); static inline void mm_copy_segments(struct mm_struct *from_mm,
arch/unicore32/include/asm/processor.h +0 -3
@@ -68,9 +68,6 @@ struct task_struct;/* Free all resources held by a thread. */ extern void release_thread (struct task_struct *); -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy (tsk) do { } while (0) -unsigned long get_wchan (struct task_struct *p);#define cpu_relax () barrier()
arch/x86/include/asm/processor.h +0 -3
@@ -579,9 +579,6 @@ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);/* Free all resources held by a thread. */ extern void release_thread (struct task_struct *); -/* Prepare to copy thread state - unlazy all lazy state */ -extern void prepare_to_copy (struct task_struct *tsk); -unsigned long get_wchan (struct task_struct *p);/*
arch/x86/kernel/process.c +19 -6
@@ -47,10 +47,16 @@ EXPORT_SYMBOL_GPL(idle_notifier_unregister);struct kmem_cache *task_xstate_cachep;EXPORT_SYMBOL_GPL (task_xstate_cachep); +/* +* this gets called so that we can store lazy state into memory and copy the +* current task into the new thread. +*/ int arch_dup_task_struct (struct task_struct *dst,struct task_struct *src) {int ret; +unlazy_fpu (src); + *dst = *src;if (fpu_allocated (&src->thread.fpu)) {memset (&dst->thread.fpu,0 ,sizeof (dst->thread.fpu));
@@ -81,6 +87,16 @@ void arch_task_cache_init(void) SLAB_PANIC | SLAB_NOTRACK, NULL); } +static inline void drop_fpu (struct task_struct *tsk) +{ +/* +* Forget coprocessor state.. +*/ + tsk->fpu_counter =0 ; +clear_fpu (tsk); +clear_used_math (); +} +/* * Free current thread data structures etc.. */
@@ -103,6 +119,8 @@ void exit_thread(void)put_cpu ();kfree (bp); } + +drop_fpu (me); }void show_regs (struct pt_regs *regs)
@@ -143,12 +161,7 @@ void flush_thread(void)flush_ptrace_hw_breakpoint (tsk);memset (tsk->thread.tls_array,0 ,sizeof (tsk->thread.tls_array)); -/* -* Forget coprocessor state.. -*/ - tsk->fpu_counter =0 ; -clear_fpu (tsk); -clear_used_math (); +drop_fpu (tsk); }static void hard_disable_TSC (void )
arch/x86/kernel/process_32.c +0 -9
@@ -126,15 +126,6 @@ void release_thread(struct task_struct *dead_task)release_vm86_irqs (dead_task); } -/* -* This gets called before we allocate a new thread and copy -* the current task into it. -*/ -void prepare_to_copy (struct task_struct *tsk) -{ -unlazy_fpu (tsk); -} -int copy_thread (unsigned long clone_flags,unsigned long sp,unsigned long unused,struct task_struct *p,struct pt_regs *regs)
arch/x86/kernel/process_64.c +0 -9
@@ -145,15 +145,6 @@ static inline u32 read_32bit_tls(struct task_struct *t, int tls)return get_desc_base (&t->thread.tls_array[tls]); } -/* -* This gets called before we allocate a new thread and copy -* the current task into it. -*/ -void prepare_to_copy (struct task_struct *tsk) -{ -unlazy_fpu (tsk); -} -int copy_thread (unsigned long clone_flags,unsigned long sp,unsigned long unused,struct task_struct *p,struct pt_regs *regs)
arch/x86/kernel/xsave.c +0 -2
@@ -48,8 +48,6 @@ void __sanitize_i387_state(struct task_struct *tsk)if (!fx)return ; -BUG_ON (__thread_has_fpu (tsk)); - xstate_bv = tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv;/*
arch/xtensa/include/asm/processor.h +0 -3
@@ -168,9 +168,6 @@ struct mm_struct;/* Free all resources held by a thread. */ #define release_thread (thread) do { } while(0) -/* Prepare to copy thread state - unlazy all lazy status */ -extern void prepare_to_copy (struct task_struct *); -/* Create a kernel thread without removing it from tasklists */ extern int kernel_thread (int (*fn)(void *),void * arg,unsigned long flags);
arch/xtensa/kernel/process.c +6 -3
@@ -140,13 +140,16 @@ void flush_thread(void) }/* -* This is called before the thread is copied. +* this gets called so that we can store coprocessor state into memory and +* copy the current task into the new thread. */ -void prepare_to_copy (struct task_struct *tsk) +int arch_dup_task_struct (struct task_struct *dst,struct task_struct *src) {#if XTENSA_HAVE_COPROCESSORS -coprocessor_flush_all (task_thread_info (tsk)); +coprocessor_flush_all (task_thread_info (src));#endif + *dst = *src; +return 0 ; }/*
fs/exec.c +14 -1
@@ -1930,8 +1930,21 @@ static int coredump_wait(int exit_code, struct core_state *core_state) core_waiters =zap_threads (tsk, mm, core_state, exit_code);up_write (&mm->mmap_sem); -if (core_waiters >0 ) +if (core_waiters >0 ) { +struct core_thread *ptr; +wait_for_completion (&core_state->startup); +/* +* Wait for all the threads to become inactive, so that +* all the thread context (extended register state, like +* fpu etc) gets copied to the memory. +*/ + ptr = core_state->dumper.next; +while (ptr !=NULL ) { +wait_task_inactive (ptr->task,0 ); + ptr = ptr->next; + } + }return core_waiters; }
kernel/fork.c +0 -2
@@ -261,8 +261,6 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)int node =tsk_fork_get_node (orig);int err; -prepare_to_copy (orig); - tsk =alloc_task_struct_node (node);if (!tsk)return NULL ;