aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r--arch/mips/kernel/process.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index bf85cc180d91..d295bd1e4996 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -107,8 +107,11 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
107 return 0; 107 return 0;
108} 108}
109 109
110/*
111 * Copy architecture-specific thread state
112 */
110int copy_thread(unsigned long clone_flags, unsigned long usp, 113int copy_thread(unsigned long clone_flags, unsigned long usp,
111 unsigned long arg, struct task_struct *p) 114 unsigned long kthread_arg, struct task_struct *p)
112{ 115{
113 struct thread_info *ti = task_thread_info(p); 116 struct thread_info *ti = task_thread_info(p);
114 struct pt_regs *childregs, *regs = current_pt_regs(); 117 struct pt_regs *childregs, *regs = current_pt_regs();
@@ -123,11 +126,12 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
123 childksp = (unsigned long) childregs; 126 childksp = (unsigned long) childregs;
124 p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); 127 p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1);
125 if (unlikely(p->flags & PF_KTHREAD)) { 128 if (unlikely(p->flags & PF_KTHREAD)) {
129 /* kernel thread */
126 unsigned long status = p->thread.cp0_status; 130 unsigned long status = p->thread.cp0_status;
127 memset(childregs, 0, sizeof(struct pt_regs)); 131 memset(childregs, 0, sizeof(struct pt_regs));
128 ti->addr_limit = KERNEL_DS; 132 ti->addr_limit = KERNEL_DS;
129 p->thread.reg16 = usp; /* fn */ 133 p->thread.reg16 = usp; /* fn */
130 p->thread.reg17 = arg; 134 p->thread.reg17 = kthread_arg;
131 p->thread.reg29 = childksp; 135 p->thread.reg29 = childksp;
132 p->thread.reg31 = (unsigned long) ret_from_kernel_thread; 136 p->thread.reg31 = (unsigned long) ret_from_kernel_thread;
133#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 137#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
@@ -139,6 +143,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
139 childregs->cp0_status = status; 143 childregs->cp0_status = status;
140 return 0; 144 return 0;
141 } 145 }
146
147 /* user thread */
142 *childregs = *regs; 148 *childregs = *regs;
143 childregs->regs[7] = 0; /* Clear error flag */ 149 childregs->regs[7] = 0; /* Clear error flag */
144 childregs->regs[2] = 0; /* Child gets zero as return value */ 150 childregs->regs[2] = 0; /* Child gets zero as return value */