process.c (f9cd49033b349b8be3bb1f01b39eed837853d880) | process.c (2319295dd8dbd076afa136bffb797ef726b605a0) |
---|---|
1/* 2 * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> 3 * Copyright (C) 2008-2009 PetaLogix 4 * Copyright (C) 2006 Atmark Techno, Inc. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. --- 105 unchanged lines hidden (view full) --- 114 } 115} 116 117void flush_thread(void) 118{ 119} 120 121int copy_thread(unsigned long clone_flags, unsigned long usp, | 1/* 2 * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> 3 * Copyright (C) 2008-2009 PetaLogix 4 * Copyright (C) 2006 Atmark Techno, Inc. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. --- 105 unchanged lines hidden (view full) --- 114 } 115} 116 117void flush_thread(void) 118{ 119} 120 121int copy_thread(unsigned long clone_flags, unsigned long usp, |
122 unsigned long unused, | 122 unsigned long arg, |
123 struct task_struct *p, struct pt_regs *regs) 124{ 125 struct pt_regs *childregs = task_pt_regs(p); 126 struct thread_info *ti = task_thread_info(p); 127 | 123 struct task_struct *p, struct pt_regs *regs) 124{ 125 struct pt_regs *childregs = task_pt_regs(p); 126 struct thread_info *ti = task_thread_info(p); 127 |
128 if (unlikely(p->flags & PF_KTHREAD)) { 129 /* if we're creating a new kernel thread then just zeroing all 130 * the registers. That's OK for a brand new thread.*/ 131 memset(childregs, 0, sizeof(struct pt_regs)); 132 memset(&ti->cpu_context, 0, sizeof(struct cpu_context)); 133 ti->cpu_context.r1 = (unsigned long)childregs; 134 ti->cpu_context.r20 = (unsigned long)usp; /* fn */ 135 ti->cpu_context.r19 = (unsigned long)arg; 136 childregs->pt_mode = 1; 137 local_save_flags(childregs->msr); 138#ifdef CONFIG_MMU 139 ti->cpu_context.msr = childregs->msr & ~MSR_IE; 140#endif 141 ti->cpu_context.r15 = (unsigned long)ret_from_kernel_thread - 8; 142 return 0; 143 } |
|
128 *childregs = *regs; | 144 *childregs = *regs; |
129 if (user_mode(regs)) 130 childregs->r1 = usp; 131 else 132 childregs->r1 = ((unsigned long) ti) + THREAD_SIZE; | 145 childregs->r1 = usp; |
133 | 146 |
134#ifndef CONFIG_MMU | |
135 memset(&ti->cpu_context, 0, sizeof(struct cpu_context)); 136 ti->cpu_context.r1 = (unsigned long)childregs; | 147 memset(&ti->cpu_context, 0, sizeof(struct cpu_context)); 148 ti->cpu_context.r1 = (unsigned long)childregs; |
149#ifndef CONFIG_MMU |
|
137 ti->cpu_context.msr = (unsigned long)childregs->msr; 138#else | 150 ti->cpu_context.msr = (unsigned long)childregs->msr; 151#else |
152 childregs->msr |= MSR_UMS; |
|
139 | 153 |
140 /* if creating a kernel thread then update the current reg (we don't 141 * want to use the parent's value when restoring by POP_STATE) */ 142 if (kernel_mode(regs)) 143 /* save new current on stack to use POP_STATE */ 144 childregs->CURRENT_TASK = (unsigned long)p; 145 /* if returning to user then use the parent's value of this register */ 146 147 /* if we're creating a new kernel thread then just zeroing all 148 * the registers. That's OK for a brand new thread.*/ 149 /* Pls. note that some of them will be restored in POP_STATE */ 150 if (kernel_mode(regs)) 151 memset(&ti->cpu_context, 0, sizeof(struct cpu_context)); 152 /* if this thread is created for fork/vfork/clone, then we want to 153 * restore all the parent's context */ 154 /* in addition to the registers which will be restored by POP_STATE */ 155 else { 156 ti->cpu_context = *(struct cpu_context *)regs; 157 childregs->msr |= MSR_UMS; 158 } 159 160 /* FIXME STATE_SAVE_PT_OFFSET; */ 161 ti->cpu_context.r1 = (unsigned long)childregs; | |
162 /* we should consider the fact that childregs is a copy of the parent 163 * regs which were saved immediately after entering the kernel state 164 * before enabling VM. This MSR will be restored in switch_to and 165 * RETURN() and we want to have the right machine state there 166 * specifically this state must have INTs disabled before and enabled 167 * after performing rtbd 168 * compose the right MSR for RETURN(). It will work for switch_to also 169 * excepting for VM and UMS --- 34 unchanged lines hidden (view full) --- 204 /* Check whether the thread is blocked in resume() */ 205 if (in_sched_functions(ctx->r15)) 206 return (unsigned long)ctx->r15; 207 else 208 return ctx->r14; 209} 210#endif 211 | 154 /* we should consider the fact that childregs is a copy of the parent 155 * regs which were saved immediately after entering the kernel state 156 * before enabling VM. This MSR will be restored in switch_to and 157 * RETURN() and we want to have the right machine state there 158 * specifically this state must have INTs disabled before and enabled 159 * after performing rtbd 160 * compose the right MSR for RETURN(). It will work for switch_to also 161 * excepting for VM and UMS --- 34 unchanged lines hidden (view full) --- 196 /* Check whether the thread is blocked in resume() */ 197 if (in_sched_functions(ctx->r15)) 198 return (unsigned long)ctx->r15; 199 else 200 return ctx->r14; 201} 202#endif 203 |
212static void kernel_thread_helper(int (*fn)(void *), void *arg) 213{ 214 fn(arg); 215 do_exit(-1); 216} 217 218int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) 219{ 220 struct pt_regs regs; 221 222 memset(®s, 0, sizeof(regs)); 223 /* store them in non-volatile registers */ 224 regs.r5 = (unsigned long)fn; 225 regs.r6 = (unsigned long)arg; 226 local_save_flags(regs.msr); 227 regs.pc = (unsigned long)kernel_thread_helper; 228 regs.pt_mode = 1; 229 230 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, 231 ®s, 0, NULL, NULL); 232} 233EXPORT_SYMBOL_GPL(kernel_thread); 234 | |
235unsigned long get_wchan(struct task_struct *p) 236{ 237/* TBD (used by procfs) */ 238 return 0; 239} 240 241/* Set up a thread for executing a new program */ 242void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp) --- 19 unchanged lines hidden --- | 204unsigned long get_wchan(struct task_struct *p) 205{ 206/* TBD (used by procfs) */ 207 return 0; 208} 209 210/* Set up a thread for executing a new program */ 211void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp) --- 19 unchanged lines hidden --- |