diff options
Diffstat (limited to 'arch/mips/kernel/process.c')
| -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. */ |
