diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/kernel/process.c | 36 |
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 | ||
85 | int 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 | |||
85 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 109 | int 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. */ |