process.c (f4091322d7397c8eb85c071570cab0e82ee3e261) | process.c (415bfae9e9dbc2232f1797a3ac78a22049a75e06) |
---|---|
1/* 2 * PARISC Architecture-dependent parts of process handling 3 * based on the work for i386 4 * 5 * Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org> 6 * Copyright (C) 2000 Martin K Petersen <mkp at mkp.net> 7 * Copyright (C) 2000 John Marvin <jsm at parisc-linux.org> 8 * Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org> --- 188 unchanged lines hidden (view full) --- 197} 198 199int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) 200{ 201 memcpy(r, tsk->thread.regs.fr, sizeof(*r)); 202 return 1; 203} 204 | 1/* 2 * PARISC Architecture-dependent parts of process handling 3 * based on the work for i386 4 * 5 * Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org> 6 * Copyright (C) 2000 Martin K Petersen <mkp at mkp.net> 7 * Copyright (C) 2000 John Marvin <jsm at parisc-linux.org> 8 * Copyright (C) 2000 David Huggins-Daines <dhd with pobox.org> --- 188 unchanged lines hidden (view full) --- 197} 198 199int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) 200{ 201 memcpy(r, tsk->thread.regs.fr, sizeof(*r)); 202 return 1; 203} 204 |
205/* Note that "fork()" is implemented in terms of clone, with 206 parameters (SIGCHLD, regs->gr[30], regs). */ | |
207int | 205int |
208sys_clone(unsigned long clone_flags, unsigned long usp, 209 struct pt_regs *regs) 210{ 211 /* Arugments from userspace are: 212 r26 = Clone flags. 213 r25 = Child stack. 214 r24 = parent_tidptr. 215 r23 = Is the TLS storage descriptor 216 r22 = child_tidptr 217 218 However, these last 3 args are only examined 219 if the proper flags are set. */ 220 int __user *parent_tidptr = (int __user *)regs->gr[24]; 221 int __user *child_tidptr = (int __user *)regs->gr[22]; 222 223 /* usp must be word aligned. This also prevents users from 224 * passing in the value 1 (which is the signal for a special 225 * return for a kernel thread) */ 226 usp = ALIGN(usp, 4); 227 228 /* A zero value for usp means use the current stack */ 229 if (usp == 0) 230 usp = regs->gr[30]; 231 232 return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr); 233} 234 235int 236sys_vfork(struct pt_regs *regs) 237{ 238 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL); 239} 240 241int | |
242copy_thread(unsigned long clone_flags, unsigned long usp, 243 unsigned long arg, | 206copy_thread(unsigned long clone_flags, unsigned long usp, 207 unsigned long arg, |
244 struct task_struct *p, struct pt_regs *pregs) | 208 struct task_struct *p, struct pt_regs *unused) |
245{ 246 struct pt_regs * cregs = &(p->thread.regs); 247 void *stack = task_stack_page(p); 248 249 /* We have to use void * instead of a function pointer, because 250 * function pointers aren't a pointer to the function on 64-bit. 251 * Make them const so the compiler knows they live in .text */ 252 extern void * const ret_from_kernel_thread; --- 20 unchanged lines hidden (view full) --- 273 cregs->gr[27] = ((unsigned long *)usp)[3]; 274 cregs->gr[26] = ((unsigned long *)usp)[2]; 275#else 276 cregs->gr[26] = usp; 277#endif 278 cregs->gr[25] = arg; 279 } else { 280 /* user thread */ | 209{ 210 struct pt_regs * cregs = &(p->thread.regs); 211 void *stack = task_stack_page(p); 212 213 /* We have to use void * instead of a function pointer, because 214 * function pointers aren't a pointer to the function on 64-bit. 215 * Make them const so the compiler knows they live in .text */ 216 extern void * const ret_from_kernel_thread; --- 20 unchanged lines hidden (view full) --- 237 cregs->gr[27] = ((unsigned long *)usp)[3]; 238 cregs->gr[26] = ((unsigned long *)usp)[2]; 239#else 240 cregs->gr[26] = usp; 241#endif 242 cregs->gr[25] = arg; 243 } else { 244 /* user thread */ |
281 cregs->gr[30] = usp; | 245 /* usp must be word aligned. This also prevents users from 246 * passing in the value 1 (which is the signal for a special 247 * return for a kernel thread) */ 248 if (usp) { 249 usp = ALIGN(usp, 4); 250 if (likely(usp)) 251 cregs->gr[30] = usp; 252 } |
282 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; 283 if (personality(p->personality) == PER_HPUX) { 284#ifdef CONFIG_HPUX 285 cregs->kpc = (unsigned long) &hpux_child_return; 286#else 287 BUG(); 288#endif 289 } else { 290 cregs->kpc = (unsigned long) &child_return; 291 } 292 /* Setup thread TLS area from the 4th parameter in clone */ 293 if (clone_flags & CLONE_SETTLS) | 253 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; 254 if (personality(p->personality) == PER_HPUX) { 255#ifdef CONFIG_HPUX 256 cregs->kpc = (unsigned long) &hpux_child_return; 257#else 258 BUG(); 259#endif 260 } else { 261 cregs->kpc = (unsigned long) &child_return; 262 } 263 /* Setup thread TLS area from the 4th parameter in clone */ 264 if (clone_flags & CLONE_SETTLS) |
294 cregs->cr27 = pregs->gr[23]; | 265 cregs->cr27 = cregs->gr[23]; |
295 } 296 297 return 0; 298} 299 300unsigned long thread_saved_pc(struct task_struct *t) 301{ 302 return t->thread.regs.kpc; --- 38 unchanged lines hidden --- | 266 } 267 268 return 0; 269} 270 271unsigned long thread_saved_pc(struct task_struct *t) 272{ 273 return t->thread.regs.kpc; --- 38 unchanged lines hidden --- |