aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/kernel/process.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index eb76434828e8..85bff5d513e5 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -82,6 +82,30 @@ void flush_thread(void)
82{ 82{
83} 83}
84 84
85int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
86{
87 /*
88 * Save any process state which is live in hardware registers to the
89 * parent context prior to duplication. This prevents the new child
90 * state becoming stale if the parent is preempted before copy_thread()
91 * gets a chance to save the parent's live hardware registers to the
92 * child context.
93 */
94 preempt_disable();
95
96 if (is_msa_enabled())
97 save_msa(current);
98 else if (is_fpu_owner())
99 _save_fp(current);
100
101 save_dsp(current);
102
103 preempt_enable();
104
105 *dst = *src;
106 return 0;
107}
108
85int copy_thread(unsigned long clone_flags, unsigned long usp, 109int copy_thread(unsigned long clone_flags, unsigned long usp,
86 unsigned long arg, struct task_struct *p) 110 unsigned long arg, struct task_struct *p)
87{ 111{
@@ -92,18 +116,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
92 116
93 childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; 117 childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32;
94 118
95 preempt_disable();
96
97 if (is_msa_enabled())
98 save_msa(p);
99 else if (is_fpu_owner())
100 save_fp(p);
101
102 if (cpu_has_dsp)
103 save_dsp(p);
104
105 preempt_enable();
106
107 /* set up new TSS. */ 119 /* set up new TSS. */
108 childregs = (struct pt_regs *) childksp - 1; 120 childregs = (struct pt_regs *) childksp - 1;
109 /* Put the stack after the struct pt_regs. */ 121 /* Put the stack after the struct pt_regs. */