process.c (f4091322d7397c8eb85c071570cab0e82ee3e261) | process.c (9ac08002130b591d0f2ee035aa9062f84f2f15cb) |
---|---|
1/* 2 * Based on arch/arm/kernel/process.c 3 * 4 * Original Copyright (C) 1995 Linus Torvalds 5 * Copyright (C) 1996-2000 Russell King - Converted to ARM. 6 * Copyright (C) 2012 ARM Ltd. 7 * 8 * This program is free software; you can redistribute it and/or modify --- 221 unchanged lines hidden (view full) --- 230 *dst = *src; 231 return 0; 232} 233 234asmlinkage void ret_from_fork(void) asm("ret_from_fork"); 235 236int copy_thread(unsigned long clone_flags, unsigned long stack_start, 237 unsigned long stk_sz, struct task_struct *p, | 1/* 2 * Based on arch/arm/kernel/process.c 3 * 4 * Original Copyright (C) 1995 Linus Torvalds 5 * Copyright (C) 1996-2000 Russell King - Converted to ARM. 6 * Copyright (C) 2012 ARM Ltd. 7 * 8 * This program is free software; you can redistribute it and/or modify --- 221 unchanged lines hidden (view full) --- 230 *dst = *src; 231 return 0; 232} 233 234asmlinkage void ret_from_fork(void) asm("ret_from_fork"); 235 236int copy_thread(unsigned long clone_flags, unsigned long stack_start, 237 unsigned long stk_sz, struct task_struct *p, |
238 struct pt_regs *regs) | 238 struct pt_regs *unused) |
239{ 240 struct pt_regs *childregs = task_pt_regs(p); 241 unsigned long tls = p->thread.tp_value; 242 243 memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context)); 244 | 239{ 240 struct pt_regs *childregs = task_pt_regs(p); 241 unsigned long tls = p->thread.tp_value; 242 243 memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context)); 244 |
245 if (likely(regs)) { 246 *childregs = *regs; | 245 if (likely(!(p->flags & PF_KTHREAD))) { 246 *childregs = *current_pt_regs(); |
247 childregs->regs[0] = 0; 248 if (is_compat_thread(task_thread_info(p))) { 249 if (stack_start) 250 childregs->compat_sp = stack_start; 251 } else { 252 /* 253 * Read the current TLS pointer from tpidr_el0 as it may be 254 * out-of-sync with the saved value. --- 6 unchanged lines hidden (view full) --- 261 childregs->sp = stack_start; 262 } 263 } 264 /* 265 * If a TLS pointer was passed to clone (4th argument), use it 266 * for the new thread. 267 */ 268 if (clone_flags & CLONE_SETTLS) | 247 childregs->regs[0] = 0; 248 if (is_compat_thread(task_thread_info(p))) { 249 if (stack_start) 250 childregs->compat_sp = stack_start; 251 } else { 252 /* 253 * Read the current TLS pointer from tpidr_el0 as it may be 254 * out-of-sync with the saved value. --- 6 unchanged lines hidden (view full) --- 261 childregs->sp = stack_start; 262 } 263 } 264 /* 265 * If a TLS pointer was passed to clone (4th argument), use it 266 * for the new thread. 267 */ 268 if (clone_flags & CLONE_SETTLS) |
269 tls = regs->regs[3]; | 269 tls = childregs->regs[3]; |
270 } else { 271 memset(childregs, 0, sizeof(struct pt_regs)); 272 childregs->pstate = PSR_MODE_EL1h; 273 p->thread.cpu_context.x19 = stack_start; 274 p->thread.cpu_context.x20 = stk_sz; 275 } 276 p->thread.cpu_context.pc = (unsigned long)ret_from_fork; 277 p->thread.cpu_context.sp = (unsigned long)childregs; --- 90 unchanged lines hidden --- | 270 } else { 271 memset(childregs, 0, sizeof(struct pt_regs)); 272 childregs->pstate = PSR_MODE_EL1h; 273 p->thread.cpu_context.x19 = stack_start; 274 p->thread.cpu_context.x20 = stk_sz; 275 } 276 p->thread.cpu_context.pc = (unsigned long)ret_from_fork; 277 p->thread.cpu_context.sp = (unsigned long)childregs; --- 90 unchanged lines hidden --- |